error: cannot initialize a variable of type 'Object *' with an rvalue of type 'const Object *'

Is there any way I can return a non const pointer to a const object? I have another function which calls my get function and does not have a const output such as

1
2
Node::Node(const Object& o) : object(0), next(0) {
}


1
2
3
  Object* Node::getObject(){
	Object* objectPointer = &object;//ERROR OCCURS HERE
	return objectPointer;


1
2
3
4
5
6
7
8
9
Object* BasicObject::dequeue(){
	   if(objectOne.listSize() == 0){
		   return 0;
	   }
	   else{
		    return  objectOne.getFirstNode->getObject(); //ERROR OCCURS HERE
		    objectOne.deleteFirstObject();
	   }
   } // error actually only comes from the first 2 code snippets now but this one was giving trouble before 


This code is for a linked list implementation to store Objects
Last edited on
Can't you just make the object non-const inside Node class?
The first question to be asked, is why on earth you want to de-const your objects? const signifies that it should be immutable, so there should be no reason for you need to get a 'normal' pointer to it. On the other hand, if you did, it shouldn't have been const in the first place.

However, for the sake of completeness, it is possible to remove the const from an object, though it can lead to really weird results. You can use const_cast or a C-style cast to do so, though I would highly recommend against it.

In summary, either make everything const Object*, or remove the const-ness (particularly if you think you might ever change anything). On the other hand, also consider passing values rather than pointers; they are much easier to reason about.
Is there any way I can return a non const pointer to a const object?
Notice that a const pointer and a const object are different things:

1
2
3
4
5
6
7
Object* const objectPointer = &object; // This is a const pointer to a non const object

Object const* objectPointer = &object; // This is a non const pointer to a const object
const Object* objectPointer = &object; // This is a non const pointer to a const object

const Object* const objectPointer = &object; // This is a const pointer to a const object
const Object* const objectPointer = &object; // This is a const pointer to a const object 
ok so I have reworked the code a little to get rid of the first error the getObject now reads

1
2
 Object* Node::getObject(){
	return &object;


however trying to use coder777's helpful post I am still getting errors in my dequeue this is what i have changed it to

1
2
3
4
5
6
7
8
9
10
Object* BasicObject::dequeue(){
	   if(objectOne.listSize() == 0){
		   return 0;
	   }
	   else{
                     const Object* objectPointer = &objectOne.getFirstNode()->getObject()
		    return  objectPointer; // ERROR HERE
		    objectOne.deleteFirstObject();
	   }
   }


error: non-const lvalue reference to type 'Object' cannot bind to a temporary of type 'const Object *'

and
error: cannot initialize return object of type 'Object *' with an lvalue of type 'const Object *'
In your case you should remove the const at all since you certainly want to modify the stored object (after deque).

1
2
3
                     Object* objectPointer = objectOne.getFirstNode()->getObject(); // Note: neither const nor &
		    objectOne.deleteFirstObject(); // Note: You need to do that before return
		    return objectPointer;
@gentleguy I think i just accedntally deleted that when copy pasting i have a semicolon in my code

@coder777 changing the code to your suggestion still gives me the error
error: cannot initialize a variable of type 'Object *' with an rvalue of type 'const Object *'


on the line Object* objectPointer = objectOne.getFirstNode()->getObject();

also I am new to this forum and im not sure why people are being reported? pretty certain its not me :/
Last edited on
still gives me the error
This is because getObject() still returns const Object *. You probably did not change the prototype of the function.

I suggest that you change the constructor:

Node::Node(Object* o)

There shouldn't be a const Object anywhere in the chain if you want a non const Object at the end.

im not sure why people are being reported?
Because of gentleguy troll habit.
So just checking, I have tried removing the const and now my error appears elsewhere so im assuming changing the constructor of Node::Node has worked however I just want to be sure that the object will be const even if I dont make all my pointer etc const. I have just realised that everything I need to be const in regards to Object is actually made const in the Object class so therefore while writing code for my linked list and nodes I dont really have to use the const keyword in my functions that are passing pointers/references?

Cheers @coder777 const correctness is really stuffing me up at the moment, need to do some extra reading
1
2
3
4
5
6
7
8
9
10
11
const Foo immutable;
Foo mutable;

const Foo * I_will_not_modify_what_I_point_to = &immutable; // ok
I_will_not_modify_what_I_point_to = &mutable; // ok

Foo * I_might_modify_what_I_point_to = &mutable; // ok
I_might_modify_what_I_point_to = &immutable; // will not compile

I_might_modify_what_I_point_to = I_will_not_modify_what_I_point_to; // will not compile
I_will_not_modify_what_I_point_to = I_might_modify_what_I_point_to; // ok 

In other words, you can always treat a non-const as a const, but you can never treat const as a non-const.

If you do have a const Object and you want to point to it, the pointer has to retain the constness.
If you have a pointer to const Object and you want to copy the pointer, the new pointer has to retain the constness.
@coder777 thanks you're correct I missed removing the const from a local variable for the object

@keskiverto thanks thats a good explaination but I still need to do a bit of work on my syntaxes and stuff im getting confused by things like coder777 mentioned earlier like this

1
2
Object const* objectPointer = &object; // This is a non const pointer to a const object
const Object* objectPointer = &object; // This is a non const pointer to a const object 


and how to format my pointers etc

Anyway thanks guys got my code working for now so I shall mark this thread as solved and probably start another in about 5 mins when I break it again and google is unhelpful.
Syntaxes ...

A declaration is essentially read from right to left. Therefore,

T fubar; Reads: name "fubar" is an object of type T.
T const fubar; Reads: name "fubar" is a constant object of type T.
T * fubar; Reads: name "fubar" is a pointer to constant object of type T.
T const * fubar; Reads: name "fubar" is a pointer to constant object of type T.
T * const fubar; Reads: name "fubar" is a constant pointer to object of type T.
T const * const fubar; Reads: name "fubar" is a constant pointer to constant object of type T.

However, the standard allows a different (I presume older) style too, where the const about type is on the left:
const T fubar; Reads: name "fubar" is a constant object of type T.
const T * fubar; Reads: name "fubar" is a pointer to constant object of type T.
const T * const fubar; Reads: name "fubar" is a constant pointer to constant object of type T.

These can have some constness too:
T fubar[N]; Reads: name "fubar" is an array of N type T objects.
T & fubar = gaz; Reads: name "fubar" is a reference (alias) of type T object named "gaz".
T fubar( const U & gaz ); Reads: name "fubar" is a function that returns type T object by value and requires a parameter that it can create a reference to (const -- will not modify referred parameter).


For more fun:
T * foo;, where T == U * and U == int *
Is thus
int * * * foo;
and some of those could be const ...


And ...
1
2
int * foo[7]; // an array of 7 pointers (to integers)
int (*foo)[7]; // a pointer to an array of 7 integers 


Besides, the whitespace in C/C++ is rather liberal, so preferred styles can and do differ:
1
2
3
T* bar;
T *bar;
T * bar;

Last edited on
Actually this

1
2
Object const
const Object


is the same thing just differently written. C++ allows it.
Topic archived. No new replies allowed.