Item1 指针与引用

时间:2022-05-27 00:31:41

 pointer与reference的区别总结出来就两点:
可空&可变
pointer可空且可以变, 而reference一定要初始化, 故不可能为空, 一但初始化就不可以再作为其它对象的引用, 故不可变

因为以上的区别, 它们在用法上就有了区别

1.pointer在使用前一般要判断是否为空, 不能拿来就用, 而reference似乎可以拿来就用. 少了验证一步
2.reference可以用于像重载运算符的的返回值, 如
class Temp
{
private:
 int _a;
 int _array[10];
public:
 int &operator[](int index)
 {
  return _array[index];
 }
 int &GetAr()
 {
  return _a;
 }
 int GetA()
 {
  return _a;
 };
};
这样通过
Temp obj;
obj[5] = 89; // 可以改变原数组的值
obj.GetAr() = 5;  // 这一句是不是看起来很奇怪, 引用作为返回值是可以当作左值来使用的, 这与上一句是没有区别的
obj.GetA() = 5;  // 这一句一定会报错


这样就引出了我们的一个思考:
int Hello1()
{
    static int a = 5;
 return a;
};
int &Hello2()
{
    static int a = 5;
 return a;
};
这两个函数到底有什么区别?
int main()
{
 int a1 = Hello1(); // 1
 int a2 = hello2(); // 2
 int &a3 = hello2(); // 3
 return 0;
};
1,2,3两句在运行的时候都做了什么呢? 下面是本人对这两个函数的一点看法, 说得不对, 可以指正, 我将感谢万分
1的运行: 开始调用Hello1, 在调用stack上会预留一块size=4的空间用来存放返回值, Hello1中"return a;"把a的值copy到这块空间上, 然后再把这块空间上的值copy到a1上
2的运行: 开始调用Hello2, 在调用stack上不会预留空间用来保存返回值, Hello2中的"return a;"没有做任何事, 然后把a的值copy到a2上
3的运行: 没有任何copy动作
也就是说1做了两次copy, 2做了一次copy, 3没有做copy
这一点是可以证明的, 证明如下:
#include <iostream>
using namespace std;
class A
{
public:
 A(){}
 A(const A& a){cout<<"copy"<<endl;}
};

A Get1()
{
 static A a;
 return a;
};
A &Get2()
{
 static A a;
 return a;
};

int main()
{
 A a1 = Get1();
 A a2 = Get2();
 A &a3 = Get3();
};
可以看到输出, 第一句输出了两个copy, 第二句输出了一个copy, 第三句没有输出,  证明了上面的说法

我们都知道pointer会点用size=4的空间, 那reference到底是什么呢?
如果说通过pointer访问一个对象, 那么得先找到pointer本身的地址, 再通过pointer的值来找到对象的地址, 这样才可以访问对象
而通过reference访问一个对象则不同, 直接得到了对象的地址, 通过这个地址来访问对象, 像是少了一点寻址的操作
个人感觉reference什么都不是, 没有占用内存空间

以上所述
如果参数是pointer或是referece都无关紧要的情况下, 使用reference少了寻址的操作
如果参数是对象或是reference都无关紧要的情况下, 使用reference少了对象copy的操作, 这对于大对象的copy尤为重要