原文链接:http://www.debugman.com/discussion/1654/c-const%E5%B8%B8%E7%94%A8%E6%96%B9%E6%B3%95/p1
C++的const可以非常灵活的摆放,例如:const int i、int const i、const int* p、int const *p、int* const p 等等,很多人会因此感到困惑,甚至于不使用const,我也是这样的。作为过来人,有必要说的是,其实const常用的也就这么几种(欢迎大家补遗):
1、修饰变量(variable)
const放在最前面修饰变量,例如:const int i、const int* p,这表明变量的内容不能改变,对i和*p不能进行赋值,例如 i = 20 或 *p = 20,编译器会报错。
const放在指针名称前,例如:int* const p,这表明指针的地址不能改变了,例如:++p是不允许的。
如果既想指针的内容无法改变,也想指针的指向的地址无法改变,则可以这么写:const int* const p,这也是一种常见的用法。
2、修饰函数(method)
const修饰函数常用在修饰返回值为指针的函数体上,例如:
int g = 0;
const int* GetValuePtr()
{
return &g;
}
const char* GetStr()
{
return "Hello";
}
这样就表明返回的指针指向的内容,调用者不要去改动。对于调用方,也只能声明用const修饰的指针去调用,例如:
const int* i = GetValuePtr();
const char* p = GetStr();
如1所示,这样声明指针,当然也就无法修改指针内容了。
3、修饰类成员函数(method of class)
const修饰非类的函数的果效同样作用于类成员函数上,特殊的是类的成员函数还可以在声明的末端用const修饰,例如:
class CMyClass
{
public:
CMyClass();
~CMyClass();
public:
int GetValue() const;
int* GetPtr();
private:
int m_iValue;
};
这样的意思是,在GetValue这个函数体内,是不会有改变类成员变量和调用其它非const修饰函数的举动,例如:
int CMyClass::GetValue() const
{
m_iValue = 0; //编译器会报错
GetPtr(); //编译器会报错
return m_iValue;
}
所以类的某个函数如果不会去改变类的成员变量,例如只返回某个成员变量的类函数,那么就应该在尾巴处修饰上const。
4、修饰类(class)
例如:const CMyClass o,这时的o对类成员变量和类函数的调用是有限制的:
a、能读取类的成员变量而不能去修改它;
b、只能调用末端有const修饰的函数。
class CMyClass
{
public:
CMyClass()
{
m_iValue = 0;
m_pPtr = NULL;
}
~CMyClass()
{
}
public:
int GetValue() const
{
return m_iValue;
}
int* GetPtr()
{
return m_pPtr;
}
private:
int* m_pPtr;
int m_iValue;
};
const CMyClass o;
o.GetValue(); //允许使用的方法
o.GetPtr(); //编译出错
5、注意:
使用了const后,编译器会作一些优化,例如:
const int x = 4;
TRACE("%d\n", x);
int* pX = ( int* ) (&x); //打印出来是4。
*pX = 3;
TRACE("%d\n", x); //打印出来的是什么?
打印出来还是4。因为经过编译器优化,对TRACE函数调用时,直接传了固定值(push 4)。在VC2005上以Debug和Release编译均是如此。
const能让编译器更好的理解你的程序,自然她产出的代码也就会更强壮。同时,const也可以理解为程序员之间的小默契,例如你遇到了某个const修饰的函数,你就应该知道应该乖乖地不要去动这个函数的返回值。
C++是一门不安全的语言,所以C++程序员必须要特别小心,利用C++语法提供的每一项特性来加强程序的强壮性。const能加强您程序的强壮性,所以擅以运用类似于const这样的特性(对于Java是final)是程序员的基本功,而更多的对const的体会还需要我们在实践中去领悟。
Reference:
http://www.possibility.com/Cpp/const.html
http://en.wikipedia.org/wiki/Const_correctness