The const property is not transitive, when dereferencing pointers. You access the pointer m_ptr
as read-only, but this pointer itself is not a pointer to const. You write to the object pointed to by m_ptr
, not m_ptr
itself.
You could write two getter functions instead of a public access to the m_ptr
member variable. One getter function is const and returns a pointer to const, one is not const and returns a normal pointer.
class Test {
private:
int* m_ptr;
public:
Test(int* ptr) : m_ptr(ptr) {};
const int* ptr() const { return m_ptr; }; // this overload is called for const Test object (const this*)
int* ptr() { return m_ptr; }; // this overload is called for non-const Test object
};
int main()
{
int a;
Test x(&a); // x is non-const
const Test& x2 = x; // x2 is const
int* p = x.ptr(); // okay
*p = 3; // okay
int* p2 = x2.ptr(); // error: invalid conversion from 'const int*' to 'int*'
*p2 = 4;
}
Then inside the const takeObj
you can only access the const int*
version of m_ptr
.
Bonus info:
On C the test object (if it only contained an int*
) would be a int**
. The const parameter variant would had to be a const int* const*
.