eepp eepp -3 years ago 182
C++ Question

How to use immutable object without operator=() in procedural code

Given an immutable C++ object (its members are

const
, which means its
operator=()
method does not exist), how do you implement this simple procedural pattern (which would require
Object::operator=()
to exist):

Object someObject {17};

// ...

if (...) {
someObject = Object {42};
}

// ...

use(someObject);

Answer Source

My pattern in such a situation is to extract initialization code into a function:

Object ini(...){
      if(...) {
            return Object{42};
      }
      return Object{17};
}
.....
Object someObject=ini(...);// copy constructor used (or not, because of RVO)
use(someObject);

If initialization is simple you could use:

Object someObject = ...? Object{42} : Object{17};

It is not very different to declaring your o-variable const.


If the someObject=17 is used and then replaced with someObject=42 - it's just undermining the good intentions which were pursued by declaring some members const.

There are two alternatives:

  1. declaring some members const was not such bright idea - it can be undone and an assigment operator can be added.
  2. using Object as it was meant to be used.

What should not be done lightly: making some tricks with pointers/references - it will just make your code more complex as it is. Better to use a new variable if needed:

Object someObject {17};

// ...

Object newSomeObject = ... ? Object {42} : someObject {17};  
use(newSomeObject);

In the case that copying of the old object could be a performance problem, the code can be refactored in such a way, that

use(need42(..) ? create42() : object17);

can be used without copying data. This solution assumes that use uses a const reference of its argument or the parameter is passed by-value.


In my opinion every change of an immutable object should yield a new object, otherwise, the following can happen:

ImmutableObject obj(1);
ImmutableObject &ref=obj;//ref.member=1
...
obj=ImmutableObject(2);
//ref.member!=1, that is puzzling, I assumed ref to be immutable!

Now, the user of your object (via ref) gets irritated because the object was changed! The whole point of the immutability is that you can reason, that the values never ever change. If they can change, there is not that many advantages in using "immutables" in the first place.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download