C++ const允许指定一个语义约束,编译器会强制实施这个约束,允许程序员告诉编译器某值是保持不变的。如果在编程中确实有某个值保持不变,就应该明确使用const,这样可以获得编译器的帮助。
1.const修饰成员变量
const可以用来修饰成员变量,告知编译器该成员变量是保持不变的。尤其要特别注意const修饰指针变量的情况:
1)只有一个const,如果const位于*左侧,表示指针所指向的数据是常量,不能通过解引用修改该数据;指针本身是变量,可以指向其他的内存单元。
2)只有一个const,如果const位于*右侧,表示指针本身是常量,不能指向其他内存地址;指针所指的数据可以通过解引用修改。
3)两个const,*左右各一个,则表示指针和指针所指数据都不能修改。
例子如下:
int main()
{
int a1=3; //non-const data
const int a2=a1; //const data
int *a3=&a1; //non-const data,non-const pointer
const int *a4=&a1; //const data,non-const pointer
int * const a5=&a1; //non-const data,const pointer
const int * const a6=&a1; //const data,const pointer
const int * const a7=&a1; //const data,const pointer
return 0;
}
2.const修饰函数参数
传递过来的参数在函数内不可以改变,与上面修饰变量时的性质一样。
例如:
void testModifyConst(const int _x)
{
_x=5;
}
则在编译上面这个函数时,会报错。因为_x是不可变的。
3.const修饰成员函数
1)const修饰的成员函数不能修改任何的成员变量,mutable修饰的变量除外。
2)const成员函数不能调用非const成员函数,因为非const成员函数可能会修改成员变量。
例如:
#include <iostream>
using namespace std;
class Point{
public :
Point(int _x):x(_x){}
void testConstFunction(int _x) const{
///错误,在const成员函数中,不能修改任何类成员变量
x=_x;
///错误,const成员函数不能调用非onst成员函数,因为非const成员函数可以会修改成员变量。
modify_x(_x);
}
void modify_x(int _x){
x=_x;
}
int x;
};
4.const修饰成员函数
1)指针传递
如果返回const data,non-constpointer,返回值也必须赋给const data,non-const pointer。因为指针所指向的数据是常量不能修改。
例如:
const int * mallocA() ///const data,non-const pointer
{
int *a=new int(2);
return a;
}
int main()
{
const int *a=mallocA();
///int *b=mallocA(); ///编译出错
return 0;
}
2)值传递
如果函数返回值采用”值传递方式”,由于函数会把返回值复制到外部临时存储单元中,加const修饰没有任何价值。所以,对于值传递来说,加const没有太多的意义。
5.笔试题举例
1)2014完美世界选择题第10题
print()函数是一个类的常成员函数,它无返回值,下列表示中正确的是:A
void print() const B.constvoid print() C.void constprint() D.void print(const)
解析:A中const是用来修饰成员函数,B的用法是用来修饰函数返回值,C无此类用法,D的用法是修饰函数传递的参数值。
2)2013完美世界选择题第6题
struct Thing
{
int valueA;
const int valueB;
};
Thing t;
t的成员变量valueA 和 valueB 的值分别为:C
A、0 0 B、垃圾值 0 C、无法运行 D、垃圾值 垃圾值
解析:valueB是const类型,必须要先初始化才行。