看完C++Primer第二章后,对于const,指针和引用以及后面的constexpr,auto之类的关系异常混乱,特此整理。
一、const必须初始化
const int i = 42; const int j = get_size();
二、const 和 引用
1.常量引用(对常量的引用):将引用与一个常量对象绑定
const int ci = 42; const int &r1 = ci;
2.除此之外,允许一个常量引用绑定一个非常量的对象,字面值或表达式
int i = 42; const int &r1 = i; //绑定一个非常量的对象 const int &r2 = 42; //绑定一个字面值 const int &r3 = r1 * 2; //绑定一个表达式
原因是:编译器使ri绑定了一个临时变量
int i = 42; const int temp = i; const int &r1 = temp;
其他绑定字面值,表达式都与之类似。
所以说,常量引用的初始化可以以四种方式初始化,除了显而易见的绑定常量对象外,还可以绑定非常量对象,字面值与表达式。
三、const 和 指针
1.指向常量的指针(指针指向的对象是const)
const int ci = 42; const int *cip = &ci;
完了以后就不能用pi去修改i的值了,因为i是const,pi是指向常量的指针。
另外,指向常量的指针和常量引用一样,指向的对象不一定要求一定是常量。
int i = 42; const int *cip = &i;
指向常量的指针只是说不能通过指针改变指向对象的值,但是对象的值可以由它自己改变。书上说,常量引用和指向常量的指针都是它们自以为是以为自己指向(引用)了常量,然后就束缚自己不能改变。。。嗯,好像很忠诚的赶脚。。。
2.常量指针(指针不能改变指向)(和指向常量的指针不一样)
int i = 42; int *const icp = &i; //常量指针 double pi = 3.14; const double *const cbcp = π //指向常量对象的常量指针
常量指针是专一滴,可以用它去修改指向的对象,而指向常量对象的常量指针就比较纠结了,虽然对象是它的,但是它却不能去改变,也许这个对象比较demanding吧。。。
四、顶层和底层const
顶层表示指针是专一滴,本身是一个常量。
底层表示指针是忠诚滴,所指向的对象是一个常量。
(不要因为名字想当然地弄混了!)
int *const icp = &i; //顶层 const int *cip = &i; //底层 const int ci = 42; //顶层const也可以表示任意对象是常量
特此注意一点!!!当执行对象的拷贝操作时,拷入和拷出的对象必须具有相同的底层const资格,或者两个对象的数据类型必须能够相互转换。一般来说,非常量可以转换常量,反之常量不可以转换为非常量。书中原话,好长啊。。。什么意思呢
const int *const cicp = &i; int *p = cicp; //错误,如果p->cicp,那么改变*p就可以改变cicp的值,cicp储存的是i的地址,而cicp的指向是不能变的。 int &r = ci; //错误,同理,如果r绑定了ci,那么改变r也可以改变ci,而ci是const int。
就是说,如果等号右边是 指向常量的指针,常量引用或者常量,那么等号左边必须也是 三者之一。(另外不知道上面的注释写的对不对。。。)
后续。。。
五、constexpr 和 常量表达式
六、类型别名 和 auto类型说明符