Reputation: 3191
I've been learning C++ and I am practicing with classes at the moment. I created a class that stores a name and a score of a player and defines functions to manipulate the data and show it.
One of the functions I created is to compare scores of two players and return a pointer to the player with the higher score. This is the function:
Player * Player::highestScore(Player p2)const
{
if(p2.pScore>pScore)
{
return &p2;
}
else
{
return this;
}
}
From the main I create the following players:
Player p1("James Gosling",11);
Player *p4 = new Player("Bjarne Stroustrup",5);
I call the highestScore function:
Player *highestScore = p1.highestScore(*p4);
However as you may have noticed from reading the function itself, when I return the pointer to the object that called the method (if it has a higher score), I get an error that says:
return value type does not match the function type
This problem seems to disappear when I declare the return type of the function as a const
, like this:
const Player * Player::highestScore(Player p2)const
The part that is confusing me is why does it allow me to return &p2
, which is not const
and doesn't allow me to return this
, which is a pointer to the object that called the function, which isn't a const
as well? Also even when I declare the function return type as a const, it still allows me to return &p2
, even though the argument passed to the parameter is not a const Player object?
Sorry if the question seems strange or what I'm trying to do is very bad programming, but it's just for the purpose of learning by doing it.
Upvotes: 3
Views: 2333
Reputation: 129374
When you have a "const" function, you are pretty much promising that "We will not change the object instance in this call". The compiler makes this
a const T* this
for that type of function (where T is the type of your class, e.g Player
).
Obviously, returning a pointer to something that is const
as as a non-const
pointer is a breach of the rule - because once some code has a non-const
pointer to your object, the code can modify the object... Which breaks the promise that "this function won't modify".
So adding const
to the return type from function is the right solution here.
You probably also want to change your code so that it takes a const *Player p2
as input - your current code returns a pointer to a local variable [it happens to be an argument, but it's the same principle - it doesn't exist when the function call has returned].
Edit: Unless you are actually returning a copy of something (e.g. an integer, string or a new structure allocated with for example new) in a function with const
attribute, the return type should be const
.
Upvotes: 3
Reputation: 385174
The part that is confusing me is why does it allow me to return &p2, which is not const and doesn't allow me to return this, which is a pointer to the object that called the function, which isn't a const as well?
this
is const
(or, more accurately, is a pointer-to-const
) in a const
member function, just like all the data members:
#include <iostream>
#include <type_traits>
struct A
{
void foo()
{
std::cout << std::is_same<decltype(this), const A*>::value << '\n';
}
void bar() const
{
std::cout << std::is_same<decltype(this), const A*>::value << '\n';
}
};
int main()
{
A a;
a.foo();
a.bar();
}
0
1
Also even when I declare the function return type as a const, it still allows me to return &p2, even though the argument passed to the parameter is not a const Player object?
We can't see what you tried, but presumably it was Player* const
, which is not the same as Player const*
(or const Player*
). You can add const
ness to &r2
just fine; taking const
ness away is a different story.
Upvotes: 7
Reputation: 70929
The difference between a const and non-const method is that in the first the this
pointer in const and in the latter it is not. So when you try to return non-const pointer from a const function and return this, compiler complains, because there this
is const and const-ness can not be automatically removed.
&p2
is simply a pointer to an argument and thus it is not const. Please keep in mind, though that &p2
is pointer to local variable and it is never safe to return that.
Upvotes: 3