3

I have a C++ class like that:

class Example { public: int getSomeProperty(int id) const; private: lazilyLoadSomeData(); } 

Basically getSomeProperty() return some data that has been loaded using lazilyLoadSomeData(). Since I don't want to load this data until needed, I'm calling this method within getSomeProperty()

int Example::getSomeProperty(int id) const { lazilyLoadSomeData(); // Now the data is loaded return loadedData[id]; } 

This does not work since lazilyLoadSomeData() is not const. Even though it only changes mutable data members, the compiler won't allow it. The only two solutions I can think of are:

  • Load the data in the class constructor, however I do not want to do that, as lazily loading everything makes the application faster.

  • Make lazilyLoadSomeData() const. It would work since it only changes mutable members, but it just doesn't seem right since, from the name, the method is clearly loading something and is clearly making some changes.

Any suggestion on what would be the proper way to handle this, without having to cheat the compiler (or giving up on const-correctness altogether)?

1
  • 4
    ¤ this is what the mutable keyword is for. an alternative which is more in the "cheating" direction is to keep a pointer to the data. i'm mentioning that for the express purpose of recognizing that anti-pattern and avoiding it; do use mutable for lazy data. cheers & hth., Commented Dec 17, 2011 at 14:00

3 Answers 3

4

You could make a proxy member object which you declare mutable and which encapsulates the lazy-loading policy. That proxy could itself be used from your const function. As a bonus you'll probably end up with some reusable code.

Sign up to request clarification or add additional context in comments.

1 Comment

Except that... semantically you just do the exact same thing, so one could argue it is the same issue. Honestly though, the question is "dumb" is some way, since mutable is about cheating, in a controlled way.
3

I would forward the call to a proxy object which is a mutable member of this class, something like this:

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

1 Comment

That is true when you don't use a "pImpl". But if you do there is no need for mutable. You can just modify what your pImpl points to because only the pImpl itself is const..
1

Make lazilyLoadSomeData() const. It would work since it only changes mutable members, but it just doesn't seem right since, from the name, the method is clearly loading something and is clearly making some changes.

No, it's not making some changes, at least not from the viewpoint whoever called getSomeProperty. All changes, if you're doing it right, are purely internal, and not visible in any way from the outside. This is the solution I'd choose.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.