C++的const关键字标记了一个变量(或者函数)的常量属性,程序员通过const关键字告诉编译器:这个变量是不可修改的常量,任何企图对其进行修改的操作不要通过编译。
const关键字的使用比较容易混淆,参考《Effective C++》现总结如下:
1:通过const关键字替代替代宏定义
(item 2:prefer consts enums,inlines to #defines)
在C++编程环境下,尽量通过const和enum替代#define
比如:
#define ASPECT_RATION 1.653
ASPECT_RATION 在编译之前就已经通过预处理替换成数字1.653,编译的时候,将会有多份1.653在可执行程序当中。另外1.653也不会进入符号表,会给debug造成困难。
在类定义里面,使用静态常量,有可能编译器不支持,此时,可以使用枚举实现常量的定义
class A
{
public:
//static const int a=100;//此语句编译器有可能不支持类常量声明,必须在类外定义
//通过g++实验,是可以编译通过的
enum {size=100};
int array[a];
}
另外,宏定义的函数,有可能会导致未预期的错误
//a,b取较大值
#define MAX(a,b) ( (a) > (b) ? (a) : (b))
int a=3,b=6;
int c=MAX(a,b++);
上述调用,会使得b++调用2遍,可以使用内联的函数模板实现同样的功能
template<typename T>
inline MAX(T a, T b)
{
return a > b ? a : b;
}
2:const关键字使用
const char *p;
//p是一个指向常量字符的指针,p的指向可以修改,p所指内容不得修改
p++; //OK
*p='F'; //Error
char * const p;
//p是一个指向字符的常量指针,p的指向不得修改,p所指内容可以修改
p++; //Error
*p='F'; //OK
//以上内容比较容易混淆,一个区分的方法是从右边往左边读
//const char *p; p is a pointer which pointed to a type of const char;
//char * const p; p is a const pointer whoes value can't be changed.
const char * const p;
//p是一个常量指针,指向一个常量型字符,p的指向和p指向的值都不得修改
3:const成员函数
类的定义当中,可以将某些成员函数声明为const类型,const成员函数不得修改类的成员变量。
对于一个const的实例变量,只能调用const函数(因为非const成员函数有可能修改成员变量,无法保证实例的const属性)
对于一个非const的实例变量,既可以调用const函数,也可以调用非const函数
class A
{
public:
A():a(100)
{
x=new char(100);
strcpy(x,"talk is cheap,show me the code."
}
int get_a_const() const
{
//a=10; error
//*x="F"; OK,此处是const函数争议的地方,的确没有修改指针变量,但是修改了指针指向的内容
return a;
}
int get_a_nonconst()
{
//a=10; OK
return a;
}
private:
int a;
char *x;
};
const A x;
x.get_a_const(); //OK
x.get_a_nonconst(); //Error
A y;
y.get_a_const(); //OK,非const类变量,可以调用const成员函数和非const成员函数
y.get_a_nonconst(); //OK
4:结语
我们应该在能够使用const变量的地方,尽量写上const,可以让编译器检查出语法错误,使得代码更安全,出错几率更低
如果能在编译时报错,为什么要等到运行时呢?
Use const as whenever possible