看下面这样一个例子,其中出现了9个const:
class MyClass
{【1】const int n;……【2】const char * function(【3】const int & aa) 【4】const{……}
} ;int main(void)
{【5】const MyClass c(10);【6】const char * p1;……int * 【7】const p2 = &x;【8】const int a = 10;int 【9】const b = 20;……
}
先说【4】和【5】,这两个是一对。【4】是代表“常成员函数”,是一个保证,保证不改变成员变量。【5】是代表对象c是一个常对象,常对象就像常变量一样,必须被初始化且只能在初始化时赋值,之后再也不允许修改其值。
常成员函数(即【4】)的主要特点:
1)不能更新类的成员变量
2)不能调用该类中没有用const修饰的成员函数,即只能调用常成员函数
3)可以被类中其它的成员函数调用
4)常对象(即【5】)只能调用常成员函数,而不能调用其他的成员函数。
补充:
virtual int function() const = 0;
中的const也是【4】,只不过这个是纯虚函数,没有函数体。=0
代表纯虚函数。所以const和=0得分开看。
【3】在函数调用中是最常见的,连同&一起用,提高效率的同时保证了原本的实参不会被修改。
对于【2】,可见它修饰了函数的返回值。如果与指针一起用,例如const char * functionName()
,代表返回的是常量指针;如果与引用一起用,例如const int & functionName()
,代表返回的是常引用。
常量指针:
const char * p
——该指针所指向的值是个定死的常量,不能被修改。在本例中【6】就是常量指针。常引用:
const int & a;
——不能通过常引用修改其引用的内容,但可通过其他方式修改被引用的内容 。
【7】是指针常量,顾名思义是一种常量,其值存的是一个地址,其值不可被更改。(但地址指向的那一块内存里的数据可以被更改,这是与【6】要辨析的地方。)
【8】和【9】是等价的,就是一个常量,代表a和b的值永远是这个,之后不能对a和b进行赋值操作。所以必须初始化。
【1】是常量成员变量,跟【8】【9】性质类似,必须被初始化,初始化后,不能够被修改。初始化有两种方式——
第一种:
class A
{const int n = 10; //ok,在类定义时
};
第二种:
class A
{const int n;A(int _n): n(_n) {} //ok,在初始化列表中
};
这样写编译错误:
class A
{const int n;A(int _n){n = _n; //编译错误,提示“必须是可以修改的左值”}
};
小结
本文提到了:【1】常量成员;【2】常量返回值;【3】常量参数;【4】常量成员函数;【5】常对象;【6】常量指针;【7】指针常量;【8】【9】常量。