刚学完C++中的指针,引用和const,以及三者之间的区别和联系,不免觉得有些混乱,但是仔细一想,还是对于三者的区别和联系,处理器还是处理的比较成功和细致的,因为知识所限,有错误之处,敬请指正。
首先必须要说,三者之间的关系编译器处理的是非常好的。
1.引用符号和取地址符号的区别
引用必须在开始定义的时候就赋值,所以尽管符号都是&,但是因为出现的位置不一样,那么它们之间的涵义就完全不同,比如int &a=b;这条语句,&就是个引用符号,a就是个引用。&b=&c;这条语句中&就是个取地址符号。特别注意就是引用必须在定义的时候就赋值,int &a,&a=b;这条语句是错的。
2.指针和引用的区别
引用不是对象而指针是对象,就是说指针本身有储存空间,而引用没有存储空间,所以引用不是复制而是重新起名,可以理解为C的typedef。
3.const int &b和int &b的区别,以及临时量对象的存在。
const int &b引用的绑定并不是直接绑定,而是间接绑定,它的形式是这样的:
const int &b=c;这个式子实际上等于
const int temp=c; const int &b=temp; 其中temp是个临时量对象。
这样就解释了为什么常量引用可以进行以下定义
const int &b=13;或
float c=3.14;const int &b=c;或
char c = 'a'; const int &b = c;
而上面这些语句去掉const就会出错。
那么我们也可以用下面狮子来验证临时量对象的存在
char c = 100; const int &b = c;
c = 120;
std::cout << b;
这样表达式的输出值是100而非120,里面的强制类型转换也是因为临时量对象的存在。
但是把char c改成int c,输出就变成120了,这是为什么呢?
因为
在某些情况下,编译器有必要产生临时对象。(红色字体引用来自妇联网)
- 当初始化一个常量引用(const reference)时,如果给定的初始化对象类型与目标引用类型不同(但是两者 能够相互转换),需要产生临时对象;
- 当函数的返回值是用户自定义类型,且程序中未将此返回值拷贝到其他对象中时,需要产生临时对象;
- 当给定的对象显式向自定义对象类型转换时,产生临时对象;
5.常量引用可以绑定非常量对象,而常量对象不能被非常量引用绑定。
但是常量引用不能直接给引用赋值,但是可以直接给引用绑定的对象赋值。
(我们叫对于const的引用为常量引用,但是本身来说这样并不存在,因为引用永远指向绑定的对象,所以任何引用从这层意义上来说都是常量)
6.变量引用不存在临时量对象,所以无法进行类型转换。
7.指针和const
一个指向常量的指针可以指向变量对象,但是不能用指针去改变变量的值,但可以通过其他方面改变指向对象的值(这中间没有临时量对象,不能进行类型转换),变量指针不能指向常量对象。
int a=1,c=2;
const int *b = &a;
b = &c;
std::cout << *b;
这其中输出是2,变量的值可以改变,指针也可以改变,只是不能用指针去改变变量的值。
8.指针可以指向引用吗?
可以,但是记得引用本身是没有地址的,指针指向的只是引用绑定的对象。
9.指向常量对象的常量指针
如:const int *const q=&p1;(p1 belong int )
int p1=2;
const int *const q = &p1;
p1 = 3;
std::cout << *q;
这样的输出为3,编译器是允许的
但是q本身的值是不能修改的,因为它是一个常量,也不能用q来修改p1;
但是改为int *const q = &p1;就可以利用q来修改p1;
10.指向常量的指针和绑定常量的引用,之所以可以指向(绑定)变量,是因为const限定的是指针指向,或引用绑定;指向变量的指针不能指向常量,绑定变量的引用不能绑定常量是因为不希望通过指针或引用来修改所针对的对象,所以编译器不予通过。
11.书上说过const后必须赋初值,但是读懂意思的人可以知道是有例外的比如:
const int *a;这个是可以不用赋值的,因为const这里没有限制指针,而是指针地方的限制。
const int &a这个需要赋初值是因为引用的要求而非const。
int *const a就必须赋初始值
来理解个东西,p是个指针,a是变量,p=&a,那么*p和a相同吗?答案是否定的,因为*p是位置指向,而a是变量,尽管在平时没有什么差别,但是const (某个指针指向类型)*p的时候,为什么a可以改变,因为const限制的是p地址的指向即*p,而非限制变量a。