c++classconstantsdatamember

Question about C++ pointers in a class instance declared as const


If i were to create a simple class like this:

class foo
{
  int* a;
};

and then create an instance of that class that is const: const foo; would foo's member a be a const int* or a int* const?

I feel like a would end up being a int* const but I'm pretty new to c++ so I won't blindly trust my instincts just yet. I haven't found any other references that could answer my question.


Solution

  • The data member a will behave as having the type int * const (though its type as a declared data member is still int *). You will may change an object pointed to by the pointer. But you will not may change the data member itself because you may not change a constant object of the class to which the data member belongs.

    Here is a demonstration program

    #include <iostream>
    
    int main()
    {
        struct foo
        {
            int *a;
        };
    
        int x = 10;
    
        std::cout << "x = " << x << '\n';
    
        const foo f = { &x };
    
        *f.a = 20;
    
        std::cout << "x = " << x << '\n';
    }
    

    The program output os

    x = 10
    x = 20
    

    On the other hand, you could declare the data member a with specifier mutable. In this case you may change it even if it belongs to a constant object of the class as for example

    #include <iostream>
    
    int main()
    {
        struct foo
        {
            mutable int *a;
        };
    
        int x = 10;
    
        std::cout << "x = " << x << '\n';
    
        const foo f = { &x };
    
        *f.a = 20;
    
        std::cout << "x = " << x << '\n';
    
        int y = 30;
    
        f.a = &y;
    
        std::cout << "*fa = " << *f.a << '\n';
    }
    

    The program output is

    x = 10
    x = 20
    *fa = 30
    

    By the way it is interesting to consider an example when instead of a data member of a pointer type there is declared a data member with a referenced type. Strictly speaking opposite to pointers references themselves can not be declared as constants. In any case references may not be reassigned to reference another object. So whether an object of a class type is constant or non-constant in any case you may not change its data member of a referenced type to reference another object.

    So even if an object of a class declared as constant its data member of a referenced type may change an object referenced by the data member. At the same time the object of the class type stays unchanged. Here is one more demonstration program.

    #include <iostream>
    
    int main()
    {
        struct foo
        {
            int &a;
        };
    
        int x = 10;
    
        std::cout << "x = " << x << '\n';
    
        const foo f = { x };
    
        f.a = 20;
    
        std::cout << "x = " << x << '\n';
    }
    

    Again the program output is

    x = 10
    x = 20