懒惰属性 - 有效使用可变?

时间:2014-04-25 08:02:05

标签: c++ mutable

今天我发现自己编写了一些类似下面的代码,我想知道这是否是对mutable关键字的有效使用。

我的想法是想通过const指针访问某些属性,但我只想在需要时评估这些属性。

class Person {
  public:
    Person() : age(-1) {}
    ~Person() {} 

    int GetAge() const {
      if( age == -1 ) { CalculateAge(); }
      return age;
    }

  private:
    mutable int age;

    // Note: as a result of being called from a `const` method, 
    // CalculateAge has to be const itself.
    void CalculateAge() const {
      age = 33; // do calculation based on date of birth or whatever.
    }
};

这是mutable的要点,还是我在这里滥用它? 我用自己的理由说服了上面的代码等同于

class Person {
  public:
    Person() {}
    ~Person() {} 

    int GetAge() const {
      // Always do the expensive calculation here
      return 33;
    }
};

class Person {
  public:
    Person() {
      // Do the expensive calculation here even if age is never used.
      age = 33; 
    }
    ~Person() {} 

    int GetAge() const {
      return age;
    }

  private:
    int age; // non-mutable
};

其中GetAge()被正确标记为const;它是否实际缓存结果是一个与我的类客户端无关的实现细节。

编辑:此外,我还有兴趣听取任何其他不涉及使所有内容变为非{...}}的解决方案。

2 个答案:

答案 0 :(得分:1)

不是一个完整的答案,但是,它看起来像是虐待我。您应该仅将mutable标记为不修改对象外部状态的成员。在您的情况下,您有一个方法GetAge,它公开了成员age,这意味着更改age会更改对象的“可见”状态。

修改

编辑后,我不得不说它没问题。只要您使用age之类的成员cache

答案 1 :(得分:1)

如果您希望方法为const,则可以使用

mutable,因为它不会更改对象的外部状态,但您仍需要更改某个内部状态。在我看来,这正是你在这里所拥有的。延迟计算年龄只是一些内部优化,从用户隐藏优化是合理的。用户将不理解为什么让年龄修改对象(“外部状态”)。

但是:我不喜欢可变的。如果你有一个驻留在只读内存中的const对象(例如只读文件映射),mutable可能会成为一个问题。如果然后在该对象上调用const方法,编译器将不会抱怨。但是如果你修改了一些可变对象,代码就会崩溃。