以下代码无法编译,说“错误C2248:'A :: getMe':无法访问在类'A'中声明的私有成员”。为什么?我试图调用公共接口。
class B
{
};
class A
{
public:
const B& getMe() const;
private:
B& getMe();
};
int main()
{
A a;
const B& b = a.getMe();
return 0;
}
答案 0 :(得分:15)
其他答案中未提及的部分问题是可访问性和可见性是C ++中的独立概念。 B& A::getMe()
私有成员即使无法访问,也会在main
中显示。因此,在您的致电a.getMe()
中,有两个需要考虑的重载成员,B& A::getMe()
和B const& A::getMe() const
。由于a
不是const
,因此它是被选中的私有成员。然后您会收到错误,因为它无法访问。如果您没有私有非const成员函数,那么您将使用const成员作为唯一的可能性,并且可以在非const对象上调用const成员。
请注意,如果可见性以可访问性为条件,您可能会遇到其他类型的混淆行为:您重构成员,将调用发送到类外的私有成员。现在,私人会员不再可访问,因此呼叫是公共的不同成员。行为的无声改变可能导致难以追踪的错误。
总之:无论你的语言规则是什么,永远不会因不同的可访问性而过载,这会导致混淆。
答案 1 :(得分:8)
在C ++中,您不能在返回类型上重载。基于const的重载成员函数也不例外:重载调用函数的对象的constness,而不是返回类型。
要做你想要的是一次千载难逢的机会,可以使用const_cast
添加 constness:
const B& b = const_cast<const A&>(a).getMe();
当然,虽然这很奇怪也很有趣,如果你这样做可能会更容易阅读:
const A& const_a = a;
const B& b = const_a.getMe();
答案 2 :(得分:4)
a在a.getMe()中不是const,因此编译器没有意识到你正在尝试使用方法的const重载。
A const a;
const B& b = a.getMe();
将按预期工作(除了A需要初始化)。
答案 3 :(得分:3)
这是因为通过非const方法调用const方法,应该是const以防止编译器选择非const方法。
调用私有memeber函数是不是更容易,以避免混淆两个具有相同名称但访问权限不同的函数。