Haatschii
Haatschii

Reputation: 9309

Pointers and References as member variables of const objects

The following code compiles fine. However I wonder if it is legal C++. So more specific, if I have a const object, am I allowed to modify variables through pointers/references of that object?

class Foo {
public:
    int* a;
    int& b;
    Foo(int* _a, int& _b) : a(_a), b(_b) {}
};

int main ( int argc, char* argv[] ) {
    int x = 7;
    const Foo bar(&x, x);

    *bar.a = 3; //Leagal?
    bar.b = 7; //Legal?
    return 0;
}

Upvotes: 5

Views: 2107

Answers (2)

JohnB
JohnB

Reputation: 13713

It's legal, as const-ness of the class means that the class member is constant. a is a pointer, so the address the pointer points to is constant, but the value stored at that address need not be.

Hence bar.a is effectively an int * const, not an int const *.

As, after initialization, a reference cannot be made to refer to another entity anyway, it does not matter for bar.b whether bar is declared const or not.

The constant variant of a pointer is a constant pointer, not a pointer to a constant. The constant variant of a reference is a reference, not a reference to a constant.

Small digression: You should be careful with references as members anyway in connection with const-ness, as the following will probably compile

struct Y { int m_a; };
struct X {
   const Y & m_y;
   X (const Y & y) : m_y (y) { }
};

Y y;
y.m_a = 1;
X x (y); // or const X x (y) -- does not matter
// X.m_y.m_a == 1

y.m_a = 2;
// now X.m_y.m_a == 2, although X.m_y is supposed to be const

As it is possible to assign a pointer to non-const to a pointer to const, you can build an analogous example with pointers. Remember that const does only guarantee that YOU will not modify a variable via this very variable, it cannot guarantee that the contents of the variable are not modified at all.

Upvotes: 8

JaredPar
JaredPar

Reputation: 754575

I find the best way to think about const in C++ is that it protects the physical bits of the object. It has no real protection for objects that it refers to. You can control the object definition with const methods to provide deeper protection of values but by default C++ really only protects the physical object itself

One of the reasons why C++ allows you to modify the contents of a pointer through a const value is that it really can't stop you. Imagine for a second that C++ disallowed that particular construct. You could trivially violate it by doing the following

size_t t1 = (size_t)bar.a; // legal 
int* t2 = (int*)t1;        // legal 
*t2 = 3;                   // exactly the same as *bar.a = 3

Upvotes: 3

Related Questions