Primer C++笔记
const限定符
有时候我们希望定义这样一种变量,它的值不能被改变。
特点:
-
const对象一旦创建后其值就不能再改变,所以const对象必须初始化。
-
const特征仅仅在改变const变量的操作的才会发挥作用。
-
初始值可以是任意复杂的表达式:
-
默认情况下,const对象仅在文件内有效。对于const变量不管是声明还是定义都添加extern关键字就可以在一个文件中定义const,而在其他多个文件中声明它。
-
可以把引用绑定到const对象上,就像绑定到其他对象上一样,我们称之为对常量的引用。与普通引用不同的是,对常量的引用不能被用作修改它所绑定的对象。
-
初始化和对const的引用
另外一种情况,当一个常量引用被绑定到另外一种类型:
-
对const的引用可能引用一个并非const的对象
顶层const
顶层const表示指针本身是个常量,底层const表示指针所指的对象是一个常量
int i = 0;
int *const p1 = &i; //顶层const
const int ci = 42; //顶层const
const int *p2 = &ci; //底层const
const int *const p3 = p2; //靠右的是顶层const,靠左的是底层const
const int &r = ci; //用于声明应用的const都是底层const
constexpr常量
声明为constexpr的变量一定是一个常量,并且必须用常量表达式初始化。
指针和constexpr
constexpr把它定义的对象置为了顶层const
所指向:“Hello” const限定
p:const char *p = "Hello";
q:char *q = "Hello" //错误
//case1
const char *p = "Hello";
//所指向是常量(pointer to const),强转/const_cast改变不了所指向(Hello)的const限定
//char *q = (char *)p;
char *q = const_cast<char *>(p);
*q = 'J'; //崩溃
//case2
const char * const p = "Hello";
//++p; //错误:表达式必须是可修改的左值
//拷贝p时,可以不在乎它是一个顶层const,const char *p1,在赋值給q时仍然需要强转const char * -> char *, "Hello"不能修改
//char *q = (char *)p;
char * q = const_cast<char *>(p);
++q;
//*q = 'a'; //崩溃
所指向:“Hello” 可修改
char str[] = { 'H','e', 'l', 'l', 'o', '\0' };
p:const char *p = str;
q:char *q = str
//case3
char str[] = { 'H','e', 'l', 'l', 'o', '\0' };
const char *p = str;
char *q = str;
//*p = 'J'; //错误:表达式必须是可修改的左值,虽然不能通过p来修改str,但str的内容可以通过其他指针修改
*q = 'J';
cout << q << endl; //Jello
//case4
char str[] = { 'H','e', 'l', 'l', 'o', '\0' };
const char * const p = str;
char * const q = str;
//p++ //错误:表达式必须是可修改的左值
//q++; //错误:表达式必须是可修改的左值
//强转/const_cast改变不了const pointer的const限定
//(const_cast<char *>(q))++; //错误:表达式必须是可修改的左值
//((char *)q)++; //错误:表达式必须是可修改的左值
*q = 'J';
cout << q << endl; //Jello
所指向:i const 限定
const int i = 12;
const int &cri = i;
int &ri = i; //错误
//case1
const int i = 12;
const int &cri = i;
//int &ri = i; //错误:限定符被丢弃
//cri = 13; //错误:表达式必须是可修改的左值
所指向:i 可修改
const int i = 12;
const int &cri = i;
int &ri = i;
//case2
int i = 12;
const int &cri = i;
int &ri = i;
//cri = 13; //错误:表达式必须是可修改的左值
ri = 14;
cout << i << endl; //14
//引用只是一个别名,实际上int &tmpri = i
int &tmpri = (int &)cri;
tmpri = 15;
cout << i << endl; //15