Azk Azk - 1 month ago 14
C++ Question

Make a member variable object modifiable but not assignable

I've searched high and low for the answer for this, perhaps I'm just not using the right terms to get any results?

Is there any way to make it so that a member variable is const in that it can't be reassigned, and will always be the same object, but still allow the object itself to be modified? Much like the behavior of a const pointer to a non-const object, but without being an actual pointer?

The main use case that I see for this would be composition. Let's say Foo has-a Bar, and you want to be able to access and modify that Bar, but not change which Bar Foo has. Just change the properties/call non-const methods on that Bar. Is there any way to do this?

Answer

Not with const correctness machinery; it's too primitive for that (it's just a single bit: either "change" or "not change").

You can however mark assignment private and the container a friend so that only container methods will be allowed to assign, but mutators could be marked public for others to use.

class Foo {
public:
    int x, y;
    Foo() : x(0), y(0) {}
    friend class Bar;
private:
    Foo& operator=(const Foo& other){
        ...
        return *this;
    }
};

class Bar {
public:
    Foo foo;
    Bar(){
        foo = Foo(); // OK from here
    };
};

void baz() {
    Bar bar;
    bar.foo.x = 42;   // Ok assigning a member of foo
    bar.foo = Foo();  // Invalid from here (doesn't compile)
}