非静态成员函数后面用const关键字修饰的作用
在学习boost库过程中,发现非静态成员函数后面,常常用const关键字修饰,如下<boost/timer.hpp>中timer库中的以秒为单位获取流逝时间的函数:
double elapsed() const
{
return double(std::clock() - _start_time) / CLOCKS_PER_SEC;
}
为什么非静态成员函数后面用const关键字修饰那?
因为,这么做可以提高程序的稳健性,防止误操作修改成员属性。
以下面测试用例进行验证、说明:
class Price{
public:
int Add2()const //此方法也称常函数
{
//value = value + 2; //错误1:编译器提示"表达式必须是可修改的左值"
//Add3(); //错误2:编译器提示"对象含有与成员函数”Price::Add3“不兼容的类型限定符 对象类型是:const Price"
tmp=100; //正确,因为被mutable修饰的成员可以处于不断变化的
return value;
}
int Add3()
{
value = value + 3;
return value;
}
private:
int value;
mutable int tmp;
};
错误1的原因,因为,每个对象都拥有一个记录对象内存地址的this指针,而函数末尾的const是用来修饰this指针的,即const指针指向的数据无法改动,所以,被const修饰的成员函数不能修改成员属性。
错误2的原因,因为,非const函数可能修改成员属性,而被const修饰的成员函数是不能修改成员属性的,所以,const修饰的函数不能调用非const函数。
但是,如果在属性前加上mutable关键字后,就可以修改了,如:tmp变量。mutable关键字不能修饰成员方法。
另外,普通函数后面不能用const关键字修饰,否则,会提示"非成员函数上不可以使用类型限定符"。
建议:任何不会修改数据成员的函数都应该声明为const类型,提高程序的稳健性。
为什么类成员函数不能同时用static和const关键字修饰?
因为成员函数末尾的const是用来修饰this指针的,用来防止在函数内对成员属性进行修改,而static修饰的静态成员函数,不属于具体某个对象(属于类),也就没有this指针,无法访问到对象的数据成员,两者语义冲突,因此不能同时存在。