C++Primer2.4节const 限定符知识梳理
1、const 限定符:用const定义的变量是不能改变的,所以const变量必须要初始化。
2、const的常量特征:对象的常量特征只有在执行改变对象的操作才会发挥作用。
3、const的初始化:由于const的常量特征的存在,如果利用一个对象去初始化另外一个对象,与它们是否const无关。因为初始化并不会改变const对象。
4、作用域:默认状态下,const对象仅在文件内有效:编译器会在编译的过程中把用到的变量的地方都替换成了初始值。默认状态下,const定义的变量限定了在文件内有效。当有多个文件需要使用到同名的const对象时,就需要在每个文件中定义const对象,而这些同名的const对象其实是不一样的,是独立的。这时,如果需要只在一个文件内定义一次const的对象,在其他文件只需要声明便能使用的方法是,在const变量的声明或定义前面添加关键字extern即可。
如:extern const int buff =10; //在文件a中;
extern const int buff; //在文件b中;
5、const的引用:把引用绑定在常量对象上,称之为对常量的引用。形式:const int &p=a;
①对const的引用又称为常量引用。
②引用的类型必须与其所引用对象的类型一致,但有两种例外。第一种是,初始化常量引用时允许用任意表达式来作为初始值,只要表达式的结果能够转换成引用的类型即可;尤其是允许一个常量引用绑定一个非常量的对象,字面值和一般表达式。但是,不允许一个非常量引用去绑定一个常量的对象。
③**注意点:常量引用绑定的不一定是常量对象。解释:常量引用只是自认为它绑定的是一个常量对象,但由第②点可知,其绑定对象并不一定常量对象。常量引用的作用是我们不能够通过常量引用来改变其绑定对象的值;但当其绑定对象不是常量对象时,我们可以通过另外的途径来改变其对象的值。
6、const和指针:指向常量的指针:令指针指向常量对象,其形式是const int *p=&a;
①注意点:指向常量的指针指向的不一定是常量对象,与常量引用同理。**作用:我们不能通过该指针来改变其所指向对象的值;当指向的对象不是个常量对象时,我们可以通过其他途径来改变指向对象的值。
7、const指针(常量指针):是指指针存储的地址是不能够改变的。形式:const int *const p=&a;
①常量指针一定要初始化。
②常量指针可以指向非常量的对象。
③常量指针是否可以通过指针来改变其所指向对象的值,取决于其所指向对象的数据类型。若为常量,则不可以改变;若为非常量,则可以改变。
8、顶层const和底层const
①顶层const:表示对象本身是个常量;对象的数据类型可以是指针、int型、char型等。
②底层const:表示指针指向的对象是一个常量或用于声明引用的const。
③当执行对象的拷贝操作时,常量是顶层const可以忽略掉,对拷贝操作没有影响。但当是底层const时,两个对象的底层const要相同,或者两个对象的数据类型可以转换。一般来说,非常量可以转换成常量类型,换过来则不行。
9、constexpr和常量表达式
常量表达式:是指值不会改变且在程序编译时就能得到计算结果的表达式。
constexpr:声明为constexpr的变量一定是个常量,而且必须用常量表达式来初始化。而const变量不一定是一个常量表达式,且它的表达式的计算结果知道运行时才能得到。
10、字面值类型:一般比较简单,值也容易得到的类型。算数类型、指针、引用都是字面值类型。
指针和constexptr:
①尽管指针和引用都能定义成constexpr,但它们的初始值都收到了限制。constexptr指针的初始值一定是nullptr或0,或者是存储于某个固定对象的地址。
②如果用constexpr定义了一个指针,那么限定符constexpr只对指针有效,而对指针指向的对象无效。
③constexpr指针可以指向一个非常量的对象。