Kakalokia
Kakalokia

Reputation: 3191

Returning "this" pointer in a const function

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

Answers (3)

Mats Petersson
Mats Petersson

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

Lightness Races in Orbit
Lightness Races in Orbit

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();
}

Output:

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 constness to &r2 just fine; taking constness away is a different story.

Upvotes: 7

Ivaylo Strandjev
Ivaylo Strandjev

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

Related Questions