const关键字

一、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段),只有只读属性!
posted @ 2017-07-29 09:49  沙皮狗  阅读(271)  评论(0编辑  收藏  举报