Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Const Overloading: Public-Private Lookup in C++ Class

Tags:

c++

The following code does not compile, saying " error C2248: 'A::getMe' : cannot access private member declared in class 'A'". Why? I am trying to call the public interface.

class B
{
};

class A
{
public:
    const B& getMe() const;
private:
    B& getMe(); 
};

int main()
{
A a;
const B& b = a.getMe();
return 0;
}
like image 827
amit kumar Avatar asked Sep 01 '09 10:09

amit kumar


2 Answers

Part of the problem which wasn't mentioned in other answers is that accessibility and visibility are independent concepts in C++. The B& A::getMe() private member is visible in main even if it isn't accessible. So in your call a.getMe() there are two overloaded members to consider, B& A::getMe() and B const& A::getMe() const. As a is not const it is the private member which is selected. Then you get an error because it isn't accessible. If you hadn't the private non const member function, you would have the const member as the only possibility and it would have be called as a const member can be called on non const object.

Note that if visibility was conditioned to accessibility, you could have other kind of confusing behavior: you refactor a member, putting a call to a private member outside the class. Now, the private member is no more accessible and so the call is to a different member which is public. That silent change of behavior can lead to bugs hard to track.

In conclusion: whatever are the rule of your language, never overload with different accessibility, it leads to confusion.

like image 107
AProgrammer Avatar answered Oct 11 '22 10:10

AProgrammer


In C++, you cannot overload on the return type. Overloading member functions based on their constness is no exception: You overload on the constness of the object the function is called on, not the return type.

To do what you want is a once-in-a-lifetime opportunity to use const_cast to add constness:

const B& b = const_cast<const A&>(a).getMe();

Of course, while this is strange and funny, it might be easier to read if you do it this way:

const A& const_a = a;
const B& b = const_a.getMe();
like image 9
sbi Avatar answered Oct 11 '22 10:10

sbi