C++中const的用法详解
const主要应用于以下几种情况:
(1) 声明一个对象(一个变量,或者类对象)
(2) 声明指针
(3) Const成员函数
Const对象
Const 是常量,毋庸置疑,是不能修改的,存储在内存的只读区域,因此在声明的时候必须初始化。我们要搞清楚这个实质性东西,别的都比较好理解了。
对于变量声明比较简单,就是将变量转变成常量,不能修改。
因此可以将常量传递给变量,然后就可以修改了。
例如:
int sum(int a,int b) {
a++;
return a+b;
}
int main(){
int const a=1;
int const b=2;
int c=sum(a,b);
cout<<c<<endl;
getchar();
return 0;
}
假如我们将 sum(int const a,int const b)这样传进去参数之后就变成了常量,不能修改了。
Const指针
最让我们头疼的应该是Const指针了,主要分为以下三种情况
Int const * A;
Const int *A;
Int *const A;
前两种一样,都说明指针指向的对象是常量,这个因此开始时必须给出指针指出的对象内容,以后不能修改了。
最后一个是说明指针是常量,这个开始需要给你指针的所指向的地址,该地址内的内容还可以修改。char * const z=“world”;
Const T *const P,这个是两者都可不能修改了。
总结说明:大家可以看到 * 用于区分指针是常量还是所指向的对象是常量。用*分割开就可以了。
const成员函数
一个类对象的状态由它的非静态数据成员组成。类中不需要修改对象状态的成员函数应该定义为const类型。你可以在类的成员函数的参数表后面加上关键字const来声明它为const函数。例如:
class Person{public:
int getAge() const {return age;} //const成员函数
private: int age;};
Class Person{
Public:
Int getAge() const{return age;}
Private:static int age};
Int Person::age=2;
Const成员函数中对于类中的静态数据成员可以修改,因为静态数据成员和静态函数属于类,而不属于类的对象,是所有的类对象所共有的。
到这了,顺便说一下 static的用法:
我们知道成员函数保持在栈中,只有当调用的时候才会被压栈,函数结束的时候就是释放这部分空间,导致在下一次我们还要用每个变量值的时候不存在。我们可以用全局变量,但这样会破坏类的封装性,更好的解决办法就是应用static方法,static静态数据成员,这样就可以保证某个对象的成员函数释放之后,对static值仍保持不变。
Static需要在内部声明,只能在类体外部定义。
注意const成员函数是约束语法设计(the Design byContract idiom)的一个重要的组成部分。Const成员函数确保了编程者承诺要实现的功能(如,保持对象的状态不变)由编译器强制实现。任何试图从内部修改const成员变量以及非const成员变量的举动都会导致编译时错误的产生:
int Person::getAge() const{
return ++age; //编译时出错
}
三者的联合
在下面的例子中,我们定义一个返回一个指向const整数的const指针的const成员函数:
class A{
//…
const int * const get_scores(int id) const;
};
运算符const_cast<>
const_cast<>运算符用来消除对象的const属性。不过,使用这个运算符还有几个限制,我们将简单的讨论这些限制。
消除const属性
尽管const_cast<>可以消除一个对象的const属性,但这并不意味着你就可以修改该对象。考虑下面的例子:
const char * p= “hello world”;int main() {
char * s = const_cast (p); // 消除const属性
strcpy(s, “danger!”); // 不可以,不明确的状态
}
试图重写字符串s将会导致不明确的状态。其原因是const对象可能保存在系统的只读内存中。如果你强制去除一个对象的const属性可以把该对象当着非const对象使用(例如,把它传递给一个接受char *类型参数的函数),但不能修改它。
非const型到const型的转换
绝大多数程序员不知道const_cast<>也有相反的操作,也就是说,它可以把一个非const型的对象转换为const型对象。例如:
char s[]= “fasten your seatbelt”;
size=strlen(const_cast (s));// 更明确
但是你可以看到使用const_cast<>h的机会很少,原因是C++在需要使用const型对象的环境下会自动执行非const型到const型的转换。因此,你不会真正需要这样使用const_cast<>,除非你想验证你的代码。
结论
const在语法上的障碍常常使得编程者放弃使用它,这就削弱了编程质量和产生的代码的可读性以及可维护性。诚然,指向const对象的指针和const指针的区分不应该这么容易混淆——尤其是在处理混合类型时;不过,通过检查const限定词相对星号的位置可以消除上述的模糊性,并且,const成员函数很容易辨识(const出现在参数表后)。如果你对const感到头痛的话,相信通过本文,你会发现const的妙用。