C++ Primer笔记(2.4.1)——const限定符
#include<iostream>
/******************************************************************************************/
/* 有时我们希望定义这样一种变量,它的值不能被改变。例如,用一个变量来表示缓冲区的大小。 */
/* 使用变量的好处是当我们觉得缓冲区大小不再合适时,很容易对其进行调整。另一方面,也应随 */
/* 时警惕防止程序一不小心改变了这个值。为了满足这一要求,可以用关键字const对变量的类型 */
/* 加以限定。 */
/******************************************************************************************/
int main()
{
/* ----- 例子 ----- */
const int bufSzie = 512; //定义一个变量表示缓冲区大小
//这样bufSize就被定义成了一个常量。任何试图为bufSize赋值的行为都会引发错误
//bufSzie = 512; //错误
//因为const对象一旦创建后其值就不能再改变,所以const对象必须初始化。
const int o = 42;
//const int k; //错误,没有初始化
/* --------------- */
/* ----- 初始化和const ----- */
//const类型 与 非const类型最大的区别是:
//只能在const类型的对象上执行不改变其内容的操作。例如,const int 和 普通int一样都能参与运算等等。
//在不改变const对象的操作中还有一种是初始化,如果利用一个对象去初始化另外一个对象,那它是不是const都无所谓
int i = 42;
const int ci = i; //i的值被拷贝给了ci
int j = ci; //ci的值被拷贝给了j
std::cout << "i的值为:" << i << " " << "ci的值为:" << ci << " " << "j的值为:" << j << std::endl;
std::cout << std::endl;
/* 默认情况下,const对象被设定为仅在文件内有效。当多个文件中出现了同名的const变量时, */
/* 其实等同于在不同文件中分别定义了独立的变量。 */
/* ---------------- */
/* ----- 初始化和const引用 ----- */
//可以把引用绑定到const对象上,就像绑定到其他对象上一样,我们称之为 对 常量的引用
//与普通引用不同的是,对常量的引用不能被用作修改它所绑定的对象
const int ci2 = 1024;
const int &r1 = ci2; //引用及其对应的对象都是常量
//r1 = 42; //错误,r1是对常量的引用
//int &r2 = ci; //错误,试图让一个非常量引用指向一个常量对象
/* 之前提到,引用的类型必须与其所引用对象的类型一致,但是有两个例外: */
/* 1.在初始化常量引用时允许用任意表达式作为初始值,只要该表达式的结果 */
/* 能转换成引用的类型即可 */
int y = 42;
const int &r2 = y; //允许将const int&绑定到一个普通int对象上
const int &r3 = 42; //正确:r3是一个常量引用
const int &r4 = r2 * 2; //正确:r4是一个常量引用
//int &r4 = r1 * 2; //错误:r4是一个普通的非常量引用
//想要理解这种例外情况,最简单的办法是弄清楚当一个常量引用被绑定到另外一种类型上时到底发生了什么:
double dval = 3.14;
const int &ri = dval;
std::cout << "dval的值为:" << dval << std::endl;
std::cout << "ri 的值为:" << ri << std::endl;
std::cout << std::endl;
//此处ri引用了一个int型的数。对ri的操作应该是整数运算,但dval却是一个双精度浮点数而非整数
//所以编译器把上述代码变成了如下形式
//const int temp = dval;
//const int &ri = temp;
/* ----------------------------- */
/* ----- 对const的引用可能引用一个并非const的对象 ----- */
//const引用仅对引用可参与的操作做出了限定,对于引用的对象本身是不是常量未作限定。
//因为对象也可能是个非常量,所以允许通过其他途径改变它的值:
int e = 42;
int &e1 = e;
const int &e2 = e; //e2也绑定对象e,但是不允许通过e2修改e的值
e1 = 0;
//e2 = 0; //错误
/* ---------------------------------------------------- */
return 0;
}