const:常量,不变的ios
mutable:易变的函数
从意思上理解,可见const和mutable是一对反义词,它们都是C++的关键字。this
const成员函数不能修改调用它的对象。类的成员函数能够被声明为const,这将使得函数的隐式参数this将被做为const类型的指针。这也就意味着一个const成员函数不能修改调用它的对象。并且,const对象不能调用非const成员函数。然而,const对象和非const对象均可以调用const成员函数。spa
要将一个成员函数声明为const,可使用下面的形式:.net
1
2 3 4 5 6 |
class
X { int some_var; public : int f1() const ; //const成员函数 }; |
能够看到,关键字const被放在函数声明以后。将一个成员函数声明为const的目的是防止函数修改调用它的对象。例以下面的代码:指针
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#include
<iostream> using namespace std; //说明const函数的用法,这个程序不能经过编译 class Demo { int i; public : int get() const { return i; //正确 } void seti( int x) const { i = x; //错误! }; }; void main() { Demo ob; ob.seti( 1900 ); cout << ob.get() << endl; } |
上面的这个程序不能经过编译,由于函数seti()被声明为const成员函数,这意味着在函数中不能修改调用函数的对象。可是因为seti()试图修改为员变量i,因此程序会产生错误,而在函数geti()中并不修改为员变量i,因此这个函数是正确的。orm
有时你可能想在const函数中修改类的某些成员,但又不想让函数修改类的其它成员,那么能够经过关键字mutable来实现这种功能。mutable将覆盖const属性。也就是说,在const成员函数中能够修改mutable成员,例如:对象
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
#include
<iostream> using namespace std; //能够经过编译,运行正确 class Demo { mutable int i; public : int get() const { return i; //正确 } void seti( int x) const { i = x; //错误!Maybe }; }; void main() { Demo ob; ob.seti( 1900 ); cout << ob.get() << endl; } //运行结果 1900 |
在上面的程序中,类的成员变量i被定义为mutable,因此在函数seti()中能够修改它的值。blog
const成员变量的初始化 ci
在构造函数中对成员变量进行初始化是很广泛的初始化方法,然而,这种方法并非适用于全部状况,例如:若是在类的定义中使用了const来声明成员变量,那么在类的构造函数中将不能对这些成员变量赋初始值,由于const变量必须在构造函数调用以前被初始化,在使用"引用类型的成员"以及"没有默认构造函数的成员"时存在着一样的问题,由于这些成员必须首先被初始化。为了解决这个问题,在C++中定义了一种成员初始化语法,能够在建立对象时为类的成员指定初始值。
成员初始化语法 相似于 调用基类构造函数的语法,它的通用形式以下所示:
1
2 3 4 5 6 7 |
constructor(arg_list)
: member(initlalizer) , member(initlalizer) , member(initlalizer) { //构造函数体 } |
在构造函数的后面指定你想要初始化的成员,同时用冒号将构造函数的名字和参数列表分开。也能够将基类构造函数的调用和成员的初始化放在同一参数列表中。