一、const的作用
1.定义常量,使其具有不可变性
2.进行类型检查,防止被意外的修改
3.为函数重载提供参考
1 class A 2 3 { 4 5 void fun(int i){...} 6 7 void fun(int i) const {...} 8 9 };
4.节省空间,避免不必要的内存分配
1 #define M 3 2 3 const int N = 5 //此时并未将N放入内存中 4 5 ..... 6 7 int i =N; //此时为N分配内存,以后不再分配 8 9 int I =M; //预编译期间进行宏替换,分配内存 10 11 int j = N; //没有分配内存 12 13 int J = M; //再进行宏替换,又一次分配内存
(1)const定义的只读变量在程序运行过程中只有一份拷贝,#define 定义的宏常量在内存中有若干拷贝
(2)const修饰的只读变量在编译的时候确定其值,#define 宏是在预处理阶段进行替换
(3)const修饰的只读变量具有特定的类型,#define 没有
5.提高程序的效率
编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,使得它们成为一个编译期间的常量,没有的存储和读内存的操作,使得它的效率也很高。
二、什么情况下使用const关键字
1.修饰一般常量
2.修饰常数组
1 int const a[] = {1,2,3} 2 const int a[] = {1,2,3}
3.修饰常对象
1 int const a[] = {1,2,3} 2 const int a[] = {1,2,3}
4.修饰常指针
1 const int *p; //指针p指向的内容不可变,指针本身可变,底层const 2 3 int const *p; //指针p指向的内容不可变,指针本身可变,底层const 4 5 int * const p; //指针本身不可变,指针指向的内容可变,顶层const 6 7 const int cosnt *p; //指针指向的值和指针本身都不可变
5.修饰常引用
1 const double &v;
6.修饰函数的常参数
7.修饰函数的返回值
8.修饰类的成员函数和数据成员
三、什么是常引用
1.引用的基本概念
常引用主要用于定义一个普通变量的只读属性的别名,作为函数的传入参数,避免实参在调用函数的过程中被意外的改变。
const引用的意思是对const对象的引用。如果既要利用引用提高程序的效率,又要保护传递给函数的数据不在函数中改变,就应该使用常引用。
如果是对常量进行引用,则编译器首先建立一个临时变量,然后将该变量的值置入临时变量中,对该引用的操作就是对该临时变量的操作,对常量的引用可以用其他任何引用来初始化,但不能改变。
2.引用的初始化注意事项
a)当初始化值是一个左值时(可以取得地址),没有任何问题
b)当初始化值不是一个左值时,则只能对一个常引用赋值,而且这个赋值是有一个过程的
第一步:将值隐式转化到类型T
第二步:将这个转化的结果存放在一个临时对象里
第三步:最后用这个临时对象来初始化这个引用变量
1 double &a = 2; //错误,初始化值不是左值 2 3 const double &a = 2; //正确步骤: 4 5 double temp = double(2); 6 7 const double &a = temp;
下面第一种引用方法是正确的,可以读取refVal的值,但是不能修改它,因为refVal的类型是const,任何对refVal的赋值都是不合法的(const引用是只读,常量即不能作为左值的量,定义式中赋初值除外)。
const引用可以初始化为不同类型的对象或者初始化为右值,如字面值常量,而非const引用只能绑定到与该引用同类型的对象。
1 const int val = 1024; 2 3 const int &refVal = val; //正确 4 5 int &refVal2 = val; //错误
1 const int val = 1024; 2 3 const int &refVal = val; //正确 4 5 int &refVal2 = val; //错误
3.const修饰函数参数时
1 //函数声明 2 3 void fun(string &s); 4 5 //函数调用 6 7 fun("hello world");//这种调用方式会报错!
因为"hello world"传回产生一个临时对象,而在C++中,临时对象是const类型的。因此上面的表达式就是试图将一个const类型的对象转换为非const类型,这是非法的!
1 //函数声明 2 3 void fun(const string &s); 4 5 //函数调用 6 7 fun("hello world");//正确!
四、C和C++中const的区别
1 //函数声明 2 3 void fun(const string &s); 4 5 //函数调用 6 7 fun("hello world");//正确!
C中的const机制是通过编译器的类型检查来实现的,即当编译器发现程序试图改变一个const修饰的常量时会报错。C中并没有将const类型的常量存储在只读存储区。
C++中的类型检查机制更加严谨,上面代码在C++中会报错。C++会将const修饰的常量放在只读存储区(.rodata段),或者经过编译器的优化存储在代码段(text段),只有只读属性!