如何保持这个const正确而不欺骗编译器?

时间:2011-12-17 13:57:26

标签: c++ const-correctness

我有一个像这样的C ++类:

class Example {

    public:

        int getSomeProperty(int id) const;

    private:

        lazilyLoadSomeData();

}

基本上getSomeProperty()会返回一些使用lazilyLoadSomeData()加载的数据。由于我不想在需要之前加载此数据,因此我在getSomeProperty()

中调用此方法
int Example::getSomeProperty(int id) const {
    lazilyLoadSomeData(); // Now the data is loaded
    return loadedData[id];
}

这不起作用,因为lazilyLoadSomeData()不是const。即使它只更改了可变数据成员,编译器也不会允许它。我能想到的唯一两个解决方案是:

  • 在类构造函数中加载数据,但我不想这样做,因为延迟加载所有内容会使应用程序更快。

  • 使lazilyLoadSomeData() const。它会起作用,因为它只会改变可变成员,但它似乎并不正确,因为从名称来看,该方法显然正在加载某些内容并且显然正在进行一些更改。

任何关于处理这个问题的正确方法的建议,而不必欺骗编译器(或完全放弃const正确性)?

3 个答案:

答案 0 :(得分:4)

您可以创建一个代理成员对象,声明mutable并封装延迟加载策略。该代理本身可以从您的const函数中使用。作为奖励,您可能会得到一些可重复使用的代码。

答案 1 :(得分:3)

我会将调用转发给代理对象,该代理对象是此类的mutable成员,如下所示:

class Example {

    public:

        int getSomeProperty(int id) const
        {
            m_proxy.LazyLoad();
            return m_proxy.getProperty(id);
        }

    private:

        struct LazilyLoadableData
        {
             int GetProperty(int id) const;
             void LazyLoad();
       };

     mutable LazilyLoadableData m_proxy;
};

答案 2 :(得分:1)

  

制作lazilyLoadSomeData()const。它会起作用,因为它只会改变可变成员,但它似乎并不正确,因为从名称来看,该方法显然正在加载某些内容,并且显然正在进行一些更改。

不,它没有做出一些改变,至少不是从调用getSomeProperty的观点来看。如果你做得对,所有的变化都是纯粹的内在变化,从外面看不出任何变化。这是我选择的解决方案。