标签:amp 使用 ffffff style pre 操作 修改 其他 允许
很多时候我们需要定义一种变量,而它的值是不能被改变的,这个时候我们就需要用到const限定符。
一、const对象的初始化
const对象必须在创建的时候就初始化
因为const对象在创建后就不可改变,所以创建时就应该初始化它。
1 const int i1 = 7; //正确 2 i1 = 8;//错误:不能修改const对象 3 const int i2;//错误:i2未经初始化
在不修改const对象的条件下,可以用const对象给变量赋值:
1 const int i3=7; 2 int i4=i3;//正确,此时“不修改const对象的条件下”是指i4不是一个const对象
这是因为尽管i3是一个const对象,它的值实际上却还是一个int,拷贝i3给i4赋值并不会改变i3,而且拷贝完成后,i4和i3再无关系。
二、const与引用
对const的引用常常简称为常量引用
引用的类型应该与其所引用的对象的类型一致,但是在const这里有一个例外,即:
初始化常量引用时可以用任何值作为初始值,只要该值能转换为引用的类型即可。
1 int i5 = 37; 2 const int i6 = 43; 3 const int &r1 = i5;//正确:将const int&绑定到一个普通int对象上 4 const int &r2 = i6;//正确 5 const int &r3 = 37;//正确 6 const int &r4 = i5 + 2;//正确
在这种例外情况中发生了什么呢?
实际上,对于
int i5=37;const int &r1=i5;
这种情况,编译器是这样做的:
1 int i5=37; 2 const int temp=i5; 3 const int &r1=temp;
其他的情况与之类似。
所以,当const引用绑定到非常量上时,只是保证了不通过这个const引用改变该非常量,但还有其他途径可以改变该非常量。例:
1 int i8 = 7; 2 const int &r5 = i8; 3 r5 = 8;//错误:r5是一个常量引用,不可改变 4 int &r6 = i8; 5 r6 = 9;//正确:r6是一个普通引用
所以说:要想引用const对象,就得使用常量引用;但是,常量引用引用的却不一定非得是const对象
三、指针和const
将指针和const结合,要区分指向常量的指针和常量指针
1.指向常量的指针:是指不能通过指针自身来改变其所指的对象的指针(并没有要求所指对象一定要是一个const对象),此时将*置于const之后来表示:
1 const int i9 = 7; 2 int j1 = 8; 3 const int *p1 = &i9;//正确 4 const int *p2 = &j1;//正确,可以将指向常量的指针绑定到一个非常量上 5 int *p2 = &i9;//错误:不能用普通指针指向常量对象
和常量引用一样,指向常量的指针并没有限定其所指向的对象必须是一个常量,因此,指向常量的指针只是保证了不通过指针自己来改变其所指的对象,然而有可能还可以通过其他途径来改变:
1 int j2 = 7; 2 const int *p3 = &j2; 3 *p3 = 8;//错误:p3是一个指向常量的指针 4 int *p4 = &j2; 5 *p4 = 9;//正确:p4是一个普通的指针
所以说:要想存放常量对象的地址,就得使用指向常量的指针,然而,指向常量的指针并不一定非得存放常量对象的地址
2.常量指针:指针也是一个对象,所以允许把指针本身定义为常量,此时将*置于const之前来表示:
1 int j3 = 7; 2 int *const p5 = &j3; 3 p5 = 1111;//错误:p5是一个常量,不可改变 4 *p5 = 9;//正确:p5指向的并不是一个常量
3.指向常量的常量指针:以上二者的混合体
1 const int j4 = 7; 2 const int *const p6 = &j4;//正确:const对象只能由指向常量的指针来指向 3 int j5 = 7; 4 const int *const p7 = &j5;//正确:这是因为指向常量的指针不一定非得指向const对象
四、顶层const和底层const
因为指针本身又是一个对象,它又可以指向另外一个对象,所以指针本身是不是一个常量以及指针所指的对象是不是一个常量就是两个相互独立的问题。
顶层const:表示指针本身是一个常量
底层const:表示指针所指的对象是一个常量
因此,指针既可以是顶层const,又可以是底层const
注意:用于声明引用的都是底层const
1 int j6 = 7; 2 const int *p8 = &j6;//为底层const 3 int const *p9 = &j6;//为顶层const 4 const int *const p0 = &j6;//左边的为底层const,右边的为顶层const 5 const int &r5 = j6;//底层const
顶层const和底层const在拷贝操作中区别明显:
拷贝操作中,拷入的对象(等号左边)和拷出的对象(等号右边)是否具有顶层const资格则影响不大,但必须具有相同的底层const资格,或者两个对象的数据类型可以转换,一遍来说,非常量可以转换为常量,反之则不行。
1 int j7 = 7; 2 const int *q1 = &j7;//底层const 3 int *const q2 = q1;//错误:q2具有顶层const资格却没有底层const资格,不能用具有底层const资格的q1来初始化 4 const int *const q3 = q1;//正确:q3具有底层const和顶层const资格,可以用具有底层const但不具有顶层const资格的q1来初始化 5 const int *q4 = &j7;//正确:int *可以转换为const int*
标签:amp 使用 ffffff style pre 操作 修改 其他 允许
原文地址:http://www.cnblogs.com/tom-chen/p/6658801.html