《Effective C++》中提到"尽量用编译器而不用预处理"。在C语言中,#define宏定义是很不安全的。例如
定义下面的PI:
#define PI 3.14
编译器是看不到PI这个符号的,因为在它进入编译器之前,它已经被预处理去掉,而没有保存在符号表里面。如
何有关PI的代码出错时,报错信息是指3.14,而不是PI,万一这个PI不是自己定义的,你得花多少时间把它给挖出
来!!而C++中用const代替了#define,提高了程序的可靠性和安全性。编译器通常不为const常量分配存储空
间,而是将其保存在符号表里,使得它成为编译期间的一个常量,没有存储与读内存的操作。
采用const定义常量时,常量不可再修改,因而定义时必须初始化常量。
1、使用const定义变量时,要注意以下几点:
(1) const对象默认为文件的局部变量。
在全局区域定义const变量,该变量只存在于其所在的文件中。通过指定const变量为extern,方可在整个程序中被访问。例如:
// File1
extern const int nvalue = 100;
// File2
extern const int nvalue;
cout << nvalue << endl;
(2) const引用是指向const对象的引用。
例如:
const int nValue = 100;
const int &nrefValue = nValue;
这里,可以读取但不能修改nValue、nrefValue的值。下面的赋值语句是错误的:
int &nrefValue2 = nVlaue
那是因为nrefValue2是普通的非const引用,可以用来修改nValue的值。为防止这样的修改,必须规定将普通的引用绑定到const变量是非法的。
2、const与指针一起使用,可归纳为以下3种:
(1)指向常量的指针。如:const char *ptr = "abcd" 或者 char const *ptr = “abcd”,即不可通过指针改变所指向的常量,但可移动指针。
(2)常指针。如:char* const ptr = "abcd",即该指针不能引动,但指向的数据可改变。
(3)指向常量的常指针。如:const char* const ptr = "abcd",可以看到该语句用了两个const,即指针不能移动,指向的数据也不可改变。
3、const应用于函数中:
(1)修饰形参。例如:
void Fun(const int* ptr); //保护了传入指针指向的内容;
void Fun(const int& ref); //保护了传入对象的属性。
(2)修饰返回值。例如:
const char& operator[](int &nIndex);
该函数确保了数组能读不能改。
(4)const成员函数。例如:
void Fun() const; //禁止修改成员数据(静态成员数据除外),且不能调用非const函数。
const成员函数的目的是为了指明哪个成员函数可以在const对象上被调用。在《Effective C++》中提到C++的一个容易被人忽略的重要特性:仅在const方面有不同的成员函数可以重载。举一个简单的例子:
class CTest
{
public:
void fun() const
{
{
void fun()
{
}
}
void main()
{
const CTest cObjCTest;
CTest ObjCTest;
cObjCTest.fun(); //调用const的fun()
ObjCTest.fun(); //调用非const的fun()
}