views:

58

answers:

2

Hello

I have a simple example below that does not compile. i get the following warrning about const

Error message: error C2662: 'Cfoo::GetNum' : cannot convert 'this' pointer from 'const Cfoo' to 'Cfoo &' Conversion loses qualifiers

class Cfoo 
{
    public:
        bool RunMe( const Cfoo * bar ) {
            int i = bar->GetNum() ; 
        }

        int GetNum() {
            return 7; 
        }
};   

int _tmain(int argc, _TCHAR* argv[])
{
    Cfoo a;

    Cfoo b;
    b.RunMe( &a); 

    return 0;
}

At first I though that had something to do with the GetNum not returning a const value. changing that did not seem to help.

What did I do wrong?, suggestion, hints, examples, links?

+7  A: 

GetNum must promise it does not change the value of the object by making it a const member function

class Cfoo 
{
    public:
        bool RunMe( const Cfoo * bar ) {
            int i = bar->GetNum() ; 
        }

        int GetNum() const { // !!!
            return 7; 
        }
};   
Johannes Schaub - litb
+1  A: 

litb's solution is right thereon.

However, I would like to do my bit to elaborate on what the compiler message actually means and how to decipher it.

So, here is a longer explanation of the error message and how to understand it in this context. I hope all the gurus here would correct my understanding.

"error C2662: 'Cfoo::GetNum' : cannot convert 'this' pointer from 'const Cfoo' to 'Cfoo &' Conversion loses qualifiers"

  1. The type of 'bar' is 'Cfoo const *'.

A member function such as 'GetNum' in OP is considered to be declared as

int Cfoo::GetNum(Cfoo &dummyimpliedobjectparameter); // the implied object argument as per 13.3.1/3 and /4

In accordance with 13.3.1.1.1/2

The function call bar->GetNum() is treated as (*bar).GetNum(*bar) where (*bar) is the implied object argument

Now, this means that, an object of type 'Cfoo const' has to be bound to a reference of type 'Cfoo &', to match the function call argument to the function parameter. As per 8.5.3/5', this is not allowed as a reference to non const cannot bind to a const.

So as litb suggested, the way to bail out is to make Cfoo::GetNum as a const member function. As per 13.3.1/3, with this change, the member function Cfoo::GetNum now is considered as

int Cfoo::GetNum(Cfoo const &dummyimpliedobjectparameter); // note the const

Now, the member function 'call' and 'parameter' match exactly and the code is well-formed.

@Steven: Does the compile error make more sense now?

Chubsdad