Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pointers and References as member variables of const objects

Tags:

c++

constants

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;
}
like image 301
Haatschii Avatar asked Feb 14 '14 19:02

Haatschii


1 Answers

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.

like image 178
JohnB Avatar answered Nov 28 '22 12:11

JohnB