关于两种复合类型--引用和指针以及const常量限定符的一些总结

时间:2021-01-26 20:21:42

引用(不能作为对象):

起一个另外的名字而已,好比如*文华今天叫小华,明天别人叫他小文,他还是他。

注意上述中的引用应该是指“小文”这个名字符号,而不是指小文其人,故引用不是对象!故不能定义引用的引用!而且引用不能与字面值或某个表达式结果绑定在一起,如下是错误的:int &a=10。(再注意:常量引用可以绑定字面值或一般表达式:const int &a=10正确!)


指针(可作为对象):

指向一个对象的复合类型,好比如指向一个建筑的地址牌号。注意其本身也是一个对象。


指针与引用相比:

指针本身是一个对象,存放某个对象的地址,允许对指针赋值和拷贝,在其生命周期内可先后指向不同的对象;

指针无须定义时一定赋确定的值,可用nullptr,0,NULL(头文件cstdlib)初始化一个空指针。引用必须初始化给具体的对象,并将一直绑定在一起。

总结:没有指向引用的指针,可有对指针的引用!


const限定符:

const int a=24;//const对象必须初始化,正确!

const int b;//错误!


常量引用:

相对普通引用而言,引用绑定到const对象上时,称常量引用,最大的区别是常量引用不能用作修改其绑定的对象。

(严格说,引用不是对象,不存在常量引用一说法,人们常常喜欢用它时,不过方便描述罢)


引用与const:

例1

const int a=24;

const int &b=a;//此时引用和引用对应的对象都是常量!

例2

const int a=24;

const int &b=a;

b=8;//b是对常量a的引用,此举想把a改成8,不行!

int &c=a;//c是非常量引用,想通过c改变a,但a是常量,不行!

例3

int a=24;

const int &b=a;//可以有

const int &c=8;//可以有

const int &d=b*2;//可以有

int &e=b*2;//e是一个非常量引用,不行!

例4

int a=24;

int &b=a;

const int &c=a;

b=8;//可以有

c=8;//错误!

(可见对常量引用仅对自己操作限制而已,对引用的本身是否是一个常量则不加限制!)


指针与const:

例5

const int a=24;

int  *p=&a;//错误!

const int  *p1=&a;//正确!要说明该指针指向的是常量,不能通过指针改变所指对象。不是说指针是常量!

*p1=8;//显然错误!

int b=8;

p1=&b;//正确!p1作为指向常量的指针,仅限制其本身不能改变所指对象的值,并不限制所指向对象是否常量

例6

int a=24;

int *const p=&a;//p将一直指向a,即p是常量指针!

const int b=8;

const int *const p1=&b;//p1本身是常量指针,而且指向常量对象!


提及int *const p与 const int *p区别,常有人分不清甚至说无区别······看明白了:

int *const p:指针p本身是常量,始终指向同一对象,不能改去指另外一对象!且通过p可以改变所指对象内容!

const int *p:指针p本身不是常量,可以改去指向另外一对象!但是通过p不可以改变所指对象内容!


顶层const和底层const:

指针作为一个对象,可指向另外一个对象,这两个对象是否常量是独立的。

顶层const:指针本身是const。更一般地,当任意一个对象是常量时,可称为顶层const。

底层const:指针所指对象是const。更一般地,指针与引用等复合类型的基本类型部分是常量时,可称为底层const。

int a=24;

int *const p1=&a;//const代表指针是常量,顶层。

const int b=8;//顶层

const int &c=b;//顶层

const int *p2=&b;// const代表指针所指对象是常量,底层。

const int *const p3=p2;//左边是底层const,右边是顶层const。