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