C++ 11—const用法指针
有时咱们但愿定义一个这样的变量,它的值不能被改变。例如,用一个变量来表示缓冲区的大小。使用变量的好处是当咱们以为缓冲区大小再也不适合时,很容易对其进行调整。(直接改变const定义的值便可)为了实现这一要求,能够用关键字const对变量加以限定。code
const int buffSize = 512; //输入缓冲区的大小
这样buffSize就定义成为一个常量。任何试图为buffSize赋值的行为都会引起错误:对象
buffSize = 512; //错误,试图向const对象写值
由于const对象一旦建立后其值就不能再改变,因此cosnt对象必须初始化。ip
其实const主要限定就是只能在const类型对象上执行不改变其内容的操做ci
默认状态下,const对象仅在文件内有效(当多个文件中出现同名的const变量时,其实等同于在不一样文件中分别定义了独立的变量)//解决办法:对于const变量不论是声明仍是定义都添加extern关键字编译器
1、const引用pip
引用也能够绑定到cosnt对象上,就像绑定到其余对象上同样,这称为对常量的引用。与普通引用不一样的是,对常量的引用不能被用做修改它所绑定的对象。编译
const int ci = 1024; const int &r1 = ci; //正确:引用及其对应的对象都是常量 r1 = 42; //错误:r1是对常量的引用,不能在对其进行赋值(改变常量的操做) int &r2 = ci; //错误:试图让一个很是量引用ci常量对象
初始化常量引用时容许用任意表达式做为初始值,只要该表达式的结果能转化成引用的类型便可。尤为容许为一个常量引用绑定很是量对象、字面值、甚至是一个通常表达式。
举个栗子:dva
const i = 42;
const int &r1 = i; //容许将const int& 绑定到一个普通int对象上
const int &r2 = 42; //正确:r2是一个常量引用
const int &r3 = r12; //正确:r3是一个常量引用
int &r4 = r1 2; //错误:r4是一个普通的很是量引用,而r1是一个常量引用变量
Why Wrong?
举个栗子来解释:
double dval = 3.14; const int &ri = dval;
此处ri引用了一个int型的数,对ri的操做应该是整数运算,但dval倒是一个双精度浮点数而非整数。所以为了确保让ri绑定一个整数,编译器把上述代码变成以下形式:
const int temp = dval; //由双精度浮点数生成一个临时的整形常量,即3; cosnt int &ri = temp; //让ri绑定这个临时变量
在这种状况下,ri绑定了一个临时量(temporary)对象。所谓的临时量对象就是当编译器须要一个空间来暂存表达式的求值结果时临时建立的一个未命名的对象。
2、const与指针的故事
与引用同样,也可让指针指向常量或很是量。相似于常量引用,指向常量的指针(pointer to const)不能用于改变其所指向的对象的值。要想存放常量对象的地址,只能使用指向常量的指针:
const double pi = 3.14; //pi是个常量,它的值不能改变 double *ptr = π //错误:ptr是一个普通指针 const double *cptr = π //正确:cptr能够指向一个双精度常量 *ptr = 42; //错误:不能给*cptr赋值
指针的类型必须与其所指向的对象类型一致,可是有两个例外。第一种例外状况是容许令一个指向常量的指针指向一个很是量对象。
double dval = 3.14; //dval是一个双精度浮点数,它的值能够改变 cptr = &dval; //正确:可是不能经过cptr改变dval的值
和常量引用同样,指向常量的指针也没有规定其所指向的对象必须是一个常量。所谓指向常量的指针仅仅要求不能经过该指针来改变所指向的对象的值(其实仍是能够经过其余方式改变被指向对象的值)。
const指针
指针是对象而引用不是,所以就像其余对象类型同样,容许把指针自己定义为常量,即为常量指针。指针常量必须初始化,并且一旦初始化完成,则它的值(也就是存放在指针中的那个地址)就不能再改变了。
int errNumb = 0; int *const curErr = &errNumb; //curErr将一直指向errNumb const double pi = 3.14159; const double *const pip = π //pip是一个指向常量的常量指针
错误的栗子:
*pip = 2.72; //错误:pip是一个指向常量的常量指针(错在指向常量就不能再向常量赋值) if(*curErr) { //若是curErr所指向的对象(也就是errNumb)的值不为零 errorHandler(); *curErr = 0; //正确:把curErr所指向的对象的值重置(curErr自己保存的地址不能改变,curErr是常量指针) }
3、顶层const
如前所述,指针自己是一个对象,他又能够指向另一个对象。所以,指针自己是否是常量以及指针所指的是否是一个常量就是俩个相互独立的问题。用名词顶层const(top-level const)表示指针自己是一个常量,而用名词底层cosnt(low-level const)表示指针所知的对象是一个常量。