Question

Today I found myself writing a bit of code like the following, and I was wondering if this is a valid use of the mutable keyword.

The idea is that I want to access some properties through a const pointer, but I only want to evaluate the properties when I need them.

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.
    }
};

Is this the point of mutable, or am I abusing it here? I was convincing myself with the reasoning that conceptually the above code is equivalent to

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

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

or

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
};

where GetAge() is correctly marked as const; whether it actually caches the result is an implementation detail that is irrelevant to the client of my class.

Edit: In addition I would be interested in hearing any other solutions that do not involve making everything non-const.

Was it helpful?

Solution

mutable can be used if you want a method to be const because it does not change the external state of an object, but you still need to change some internal state. In my opinion this is exactly what you have here. The deferred calculation of age is just some internal optimization and it reasonable to hide that optimization from the user. The user will not understand why getting the age modifies the object ('s external state).

But: I do not like mutable. mutable can be a problem if you have a const object which resides in read-only memory (e.g. read only file mapping). If you then call a const method on that object, the compiler will not complain. But the code will crash if you modify some mutable object.

OTHER TIPS

Not a complete answer, but yes, it looks like and abuse to me. You should mark mutable only members that do not modify the external state of the object. In your case you have a method GetAge which exposes the member age which means that changing age changes the “visible” state of the object.

edit

After your edits, I have to say that it is ok. As long as you use the member age like a cache.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top