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

来源:互联网 发布:cmmi3软件开发流程 编辑:程序博客网 时间:2024/06/05 04:51

上接: 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