views:

98

answers:

2
class A{
private:
    int a;
public:
    A() {a = 4;}
    const int& random1() const {return a; }
    //int&     random2() const {return a; }
    const int* random3() const {return &a;}
    //int*     random4() const {return &a;}
};

int main(){
    A objA;
    cout<<objA.random1()<<"\n";
    cout<<*objA.random3()<<"\n";
}

random2() and random4() are not permitted as defined above. I somehow knew this all along but never came across it while writing my own code, until today.

What all except these two cases is not permitted in const member functions?

Any reference to C++ standard text will also be helpful. Thanks!

+10  A: 

First understand that const T* is a pointer to some T that cannot be changed. The second thing to remember is all members are actually accessed via this->.

So (§9.3.1):

A nonstatic member function may be declared const, volatile, or const volatile. These cvqualifiers affect the type of the this pointer (9.3.2).

And what it does (§9.3.2):

In the body of a nonstatic (9.3) member function, the keyword this is a non-lvalue expression whose value is the address of the object for which the function is called. The type of this in a member function of a class X is X*. If the member function is declared const, the type of this is const X*, if the member function is declared volatile, the type of this is volatile X*, and if the member function is declared const volatile, the type of this is const volatile X*.

A const on a function makes the this pointer const T*.

This is why those examples fail: In the int& variant, a is accessed as this->a, this is const T*, so a is a const int. And const int cannot be implicitly converted to int&. Same with the other function.

In other words, when a function is const it smacks a const on everything in the class, and you can't implicitly cast the const away.

GMan
A: 

Const member functions can't call non-const member function, even if they don't change any member data. Sometimes you need to provide both const and non-const versions of the same function, because this pointer is implicitly passed to member functions and plays a role in overload resolution.