常成员函数的声明原则

对那些不会改变对象状态的函数,都应当将其声明为常成员函数、那么,什么是改变对象状态呢?
按照语言要求,凡是会改变非静态的成员对象值的成员函数,都不能够声明为常成员函数。但是这并不意味着,凡是不会改变非静态成员对象的成员函数,都不会改变对象的状态。 思考下,如果不改变任何一个成员对象的值,怎么会改变对象状态呢?
另一种意外情况,如果一个函数会改变某个成员对象的值,但他未必会改变对象的状态。成员状态的改变,并不能够完全根据成员对象的值是否被改变来判定,而应当根据通过这个对象对外接口所反映出的信息来判断。 如果对一个成员函数的调用,不会使得其后对该对象的接口调用的结果发生变化,那么就可以认为这个成员函数不会改变对象的状态。

class Line
{
public:
	Line(const Point p1, const Point p2) :p1(p1), p2(p2), len(-1) {};
	double getLen();

private:
	Point p1, p2;
	double len;
};

double Line::getLen()
{
	if (len < 0) {
		double x = p1.getX() - p2.getX();
		double y = p1.getY() - p2.getY();
		len = sqrt(x *x + y*y);
	}
	return len;
}

getLen函数只改变了len的值,而Line所表示的线段的状态,只由他的两个端点p1和p2决定,线段的长度依赖于它的端点位置,len成员只是用来将线段长度暂时记录下来,使得下次无需从新计算,因此改变len的值不会导致对象的状态改变。
这样问题就出现了。既然调用getLen不会改变对象状态,就应当将其声明为常成员函数,然而,语言上不允许,因为它会改变数据成员len的值。需要用到新的关键词—mutable。对于这类数据成员,可以使用mutable关键字加以修饰,这样,及时在常成员函数中。也可以修改他们的值、

class Line
{
public:
	Line(const Point p1, const Point p2) :p1(p1), p2(p2), len(-1) {};
	double getLen() const;

private:
	Point p1, p2;
	mutable double len;
};

double Line::getLen() const
{
	if (len < 0) {
		double x = p1.getX() - p2.getX();
		double y = p1.getY() - p2.getY();
		len = sqrt(x *x + y*y);
	}
	return len;
}

其实mutable不只允许在常成员函数中修改被它修饰的数据成员,被mutable修饰的成员对象在任何时候都不会被视为常对象。
参考文献《C++语言程序设计》 清华大学 郑莉老师

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值