Effective C++解析 Item3:尽量使用const (补充)物理的与逻辑的常量性

上接: Effective C++解析 Item3:尽量使用const
(续)

const 修饰成员函数

const修饰成员函数的具体含义:
有两种认同观点:
1. 物理常量性:当且仅当函数不修改任何成员数据时,可以使用const修饰成员函数。
2. 逻辑常量性:常成员函数仅可以在使用者未察觉的情况下修改成员数据。

逻辑常量性:一个成员函数在逻辑上是const,但它却仍需要改变某个成员的值。对于用户而言,这个函数看似没有改变其对象的状态,然而,它却可能更新了某些用户不能直接访问的细节。这通常被称为逻辑的常量性。

比如想在CTextBlock这个类中添加const 成员函数:

class CTextBlock {
public:
    ...
    std::size_t length() const;
private:
    char *pText;
    std::size_t textLength; // these data members can not
    bool lengthIsValid; // be modified
}; 

std::size_t CTextBlock::length() const
{
    if (!lengthIsValid) {
        textLength = std::strlen(pText); // Error!
        lengthIsValid = true; // error!
    }
    return textLength;
}

在length()成员函数中需要修改一些标记数据,或应该修改的数据,在这个例子中,需要在length调用时得到默认的文本长度,所以应该在length中修改成员数据。
但是因为const 修饰原因,在函数中直接进行改动会发生错误。

一种改变方法是在const函数中将this对象指针强制转换:

...
...

std::size_t CTextBlock::length() const
{
    if (!lengthIsValid) {
    CTextBlock * th = const_cast<CTextBlock*>(this); // const cast
        th->textLength = std::strlen(pText); // Error!
        th->lengthIsValid = true; // error!
    }
    return textLength;
}

在const函数中认为,对象的this指针是const 型对象指针,所以转换为类型指针。但是尽量不要使用const_cast进行转换。

另外一种方法,就是将需要修改的数据使用mutable修饰。
mutable特别说明这个成员需要以一种能允许更新的方式存储——即使它是某个const对象的成员。

上面的代码可以改写为:

class CTextBlock {
    public:
    ...
    std::size_t length() const;
private:
    char *pText;
    mutable std::size_t textLength; // these data members may
    mutable bool lengthIsValid; // always be modified, even in const member functions
}; 

std::size_t CTextBlock::length() const
{
    if (!lengthIsValid) {
        textLength = std::strlen(pText); // now fine
        lengthIsValid = true; // also fine
    }
    return textLength;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值