Search code examples
c++visual-studioconstants

Why can I call member's non-const function inside const member function?


When I compile below code using VisualStudio 2015, I get C2662 compiler error only on GetValueUsingObject() member function.

Code:

class Member
{
public:
    int GetValue() { _value = 1; return _value; }

private:
    int _value;
};

class Test
{
public:
    Test() : _pointer(new Member()) {}
    int GetValueUsingPointer() const { return _pointer->GetValue(); } // Okay
    int GetValueUsingObject() const { return _object.GetValue(); }    // C2662 Error

private:
    Member* _pointer;
    Member _object;
};

Compile Error Message:

C2662 'int Member::GetValue(void)' : cannot convert 'this' pointer from 'const Member' to 'Member &'

I think that both GetValueUsingPointer() and GetValueUsingObject() function violates const-ness. But, GetValueUsingPointer() has no compiling issue.

Why is it Okay?


Solution

  • You aren't calling the members function. You use a member pointer (that is const), dereference it, and call a member function of the object the pointer points to. And that object is not const.

    If pointers confuse you, consider an example where you have a member that is index into a global array:

    std::array<int,42> memory;
    
    struct foo {
        size_t index = 23;
        void bar() const {
            memory[index] = 0;  // does not modify index
        }
    };
    

    A const foo has a constant index, but you can use that index to access the index-th element in memory and modify it:

    You can imagine pointers as index into memory. A pointer that is constant does not mean that what is stored in that memory is constant. You can have a non-const pointer to constant object, const pointer to non-constant object, etc. In your constant Test the member _pointer is constant, the object it points to is not.