1.使用方法
int x=1;
ra、rb指向x,是x的另一个名字;定义ra、rb时一定要初始化。一旦初始化完成,引用将和它的初始值对象一直绑定在一起。
int &ra=x;
int &rb=ra;
pc存放变量x的地址,或者说pc是指向变量x的指针。
int *pc=&x;
int *pd=pc;
上面&x、&ra、&rb、pc、pd的值是一样的,它们都是x的值(整型1)的地址;ra、rb、*pc、*pd的值是一样的,它们都是x的值(整型1)。
x、ra、rb、*pc、*pd都是变量名,都是4字节,输出值都为1;
&x、&ra、&rb、pc、pd都是变量地址,都是8字节,输出值都为存放1的地址;意思是x、ra、rb是同一段内存,pc、pd存放这段内存的地址。
&pc、&pd都是指针变量地址,都是8字节,输出值是指针变量pc、pd的地址。
这些是非法的:
int *pe=x;
int *pf=ra;
int &rg=pc;
这是正确的:
int &rg=*pc;
2.区别:使用引用是为了避免使用指针,所以能用引用的地方就能用指针。反之则不,必须用指针的情况:
2.1分配内存和new操作符
2.2定义引用时必须初始化,这使得有时要用指针。比如一个变量定义时不初始化或初始化了但以后要另指其它对象(如类的成员变量),就需要把它定义成指针类型。当我们用set函数为它赋值时,参数也就要用指针类型。如果非要用引用类型的参数,就要把引用的地址赋值给指针,如:
int a=3;
int& b=a;
int* c=&b;
上面,指针c通过引用b指向了变量a。
2.3引用不是对象,指针是对象(C++ Primer作者说的对象不只是类的对象)。所以:
a.引用不能作为数组、容器的元素,而指针可以;
b.不能定义引用的引用,而可以定义指针的指针。
3.引用并不是指向变量的常量指针。因为引用不是对象,而指向变量的常量指针是对象:
int a=1,b=2;
int * const c=&a;
int * const d=&b;
下面的e必须初始化,不能int * const e[2]; e[0]=c; e[1]=d;
int * const e[2]={c,d};
cout<<*e[0]<<" "<<*e[1]<<endl;
上面,指向变量的常量指针c、d就可以做为数组e的对象。但是e的元素不能改变,也就是什么时候都不能有类似e[1]=c的操作。
由于引用这种初始化后不能重新绑定的限制,c、d不能作为容器的元素。
甚至定义"vector<int * const> f;"都不允许,因为定义时无法初始化。用初始化列表"vector<int * const> v{c,d};"也不行。