const 是 constant 的简写,原意是维持不变的,难于发生改变的原意。在 C++ 中用以润色内建类别表达式、自订第一类、核心成员表达式、codice、auth。
1. 润色一般类别的表达式
对基本上的数据类别,润色符 cosnt 能在类别tcsh前,也能用在类别tcsh前面,其结论是那样的。
const int a = 5; int const b = 5; const int arr1[3] = {1,2,3}; int constarr2[3] = {1,2,3};上看许多对 const 表达式的操作方式:
const int a = 10; a = 11; // 严重错误:无法为 const 表达式赋新值 int &b = a; // 严重错误:无法为 cosnt 表达式存取 non-const 提及 const int &c = a; // 正确 int *d = &a; // 严重错误:无法为 const 表达式存取指向 non-const 的指针 const int*e = &a;// 正确const 与 define 宏定义的区别:
处理阶段不同:define 是在预处理阶段,define 常量不会被编译器看到,因为在预处理阶段已经替换了;const 常量在编译阶段使用。类别和安全检查不同:define 没有类别,不做检查,仅仅是字符替换;const常量有明确的类别,在编译阶段进行类别检查;存储方式不同:define 是字符替换,有多少地方使用,就会替换多少次,不会分配内存;编译器通常不会为 const 常量分配空间,只是将它们保存在符号表内,使它们成为一个编译期间的常量,没有读取内存的操作方式,效率也很高。2. 润色指针表达式
const 润色指针表达式有三种情况:
2.1 const 润色指针指向的内容,则内容为不可表达式
const int *p = 8;const 润色指针内容,即 *p 的值不可变,只能为8。因为 const 位于 * 的左边,称为左定值。
2.2 const 润色指针,则指针为不可表达式
int a = 8; int* const p = &a; *p = 9; // 正确 int b = 7; p = &b; // 严重错误对 const 指针 p 其指向的内存地址无法发生改变,但其内容能发生改变,称为右定向,因为 cosnt 位于 * 右边。
2.3 cosnt 润色指针和指针指向的内容,则指针和指针指向的内容都为不可表达式
int a = 8; const int* const p = &a;这时 p 指向的内容和指向内容地址都已固定,不可发生改变。
3. 润色auth和codice
3.1 润色auth
值传递的 cosnt 润色:一般这种情况不需要const润色,因为表达式会自动产生临时表达式复制实参值;const 润色指针参数:防止指针被修改;cosnt 润色提及参数:为了增加效率(因为参数为提及不会创建副本)的同时防止被修改,对一般的 int、double 等内建类别,不采用引用的传递方式。3.2 润色表达式codice
润色内建类别的codice,这种情况实际无意义,因为参数返回本身就是赋值。润色自订类别的codice,此时返回的值无法作为左值使用,既无法被赋值,也无法被修改。润色指针或提及的codice,保证指针指向内容不被发生改变。4. 润色类的核心成员表达式和核心成员表达式
4.1 类的核心成员表达式
const 润色类的核心成员表达式,表示该核心成员为常量,无法不修改,只能在初始化列表中赋值。
class A { … const int nValue; //核心成员常量无法被修改 … A(int x): nValue(x) { } ; //只能在初始化列表中赋值 }4.2 类的核心成员表达式
const 润色类的核心成员表达式,表示该核心成员表达式无法修改类中的任何非 const 核心成员表达式,一般 const 写在表达式的前面,比如void func() const;。
如果有个核心成员表达式想修改第一类中的某一个核心成员表达式,能使用 mutableURL润色这个核心成员变量:
#include<iostream> using namespace std; class Test { public: Test(int _m,int _t):_cm(_m),_ct(_t){} void Kf()const { ++_cm; // 严重错误 ++_ct; // 正确 } private: int _cm; mutable int _ct; }; int main(void) { Testt(8,7); return 0; }