Reputation: 107092
I have a struct with a const pointer to an object. It is const so that the pointer won't change, I do not wish to have the object constant. I'd like to call a non-constant function in that object, thus receiving the following error:
error C2662: 'my_namespace::MyClass::myFunc' : cannot convert 'this' pointer from 'const my_namespace::MyClass' to 'my_namespace::MyClass &'
Conversion loses qualifiers
struct MyStruct
{
MyStruct( const MyClass* init_my_class_ptr );
const MyClass* my_class_ptr;
};
...
struct_instance.my_class_ptr->aNonConstFunc();
...
Assume I can't make aNonConstFunc()
const.
Upvotes: 3
Views: 4822
Reputation: 264401
The general rule is that const is applied to the object on the left of const. Unless const is the left most part of the declaration then it is applied to the right.
// Thus these two are equivalent.
const char* data1; // 'pointer to' const char (const applied to right because it has nothing on left)
char const* data2; // 'pointer to' const char
I prefer putting const on right as I can then consistently use the rule of reading types from right to left.
char const* data3; // 'pointer to' const char (reading right to left)
char* const data4; // const 'pointer to' char (reading right to left)
This is a style pref and lots of people prefer the const on the far left (and are smart enough to auto read the declaration in their head :-).
BUT Where it becomes important is when you add typedefs into the mix:
typedef is NOT a textual substitution, if defines a type alias (or synonym).
typedef char* CHARP;
const char* data5a; // 'pointer to' const char
const CHARP data5b; // const ''pointer to' char' ***(NOT THE SAME AS above)***
char* const data6a; // const 'pointer to' char
CHARP const data6b; // const ''pointer to' char'
So when you start using typedefs the meaning can change (if you put const on the far left) and just do a textual cut and paste when creating your typedefs. But th
You want a const pointer in your structure. To do this make sure the const is on the right side of the '*' symbol.
struct MyStruct
{
MyStruct(MyClass* const init_my_class_ptr)
: my_class_ptr(init_my_class_ptr)
{}
MyClass* const my_class_ptr; // const pointer to MyClass
};
Upvotes: 2
Reputation: 11516
Change your struct to:
struct MyStruct
{
MyStruct( const MyClass* init_my_class_ptr );
MyClass* const my_class_ptr;
};
That will make the pointer, instead of the pointee, const
.
More elaborate explanation (also see Wikipedia): the const
keyword is applied to whatever comes before it, except in case there's nothing in front, then it applies to what comes after it. So:
const A * object; // Non-const pointer to const A
A const * object; // Non-const pointer to const A
A * const object; // Const pointer to non-const A
const A * const object; // Const pointer to const A
A const * const object; // Const pointer to const A
Now, this is just personal preference, but this is why I always put const
after whatever is supposed to be const
. When applied everywhere in your code, this makes it very easy to figure out what exactly is supposed to be const
. No need to go decipher if the const
applies to statement before or after it.
Upvotes: 19
Reputation: 92864
Change const MyClass* my_class_ptr;
to MyClass* const my_class_ptr;
const MyClass* my_class_ptr;
declares my_class_ptr
to be a pointer to a const MyClass
object.
MyClass* const my_class_ptr
declares my_class_ptr
to be a constant pointer to a MyClass
object and that's what you need.
Upvotes: 3