Const重载:C ++类中的公共私有查找

时间:2009-09-01 10:04:17

标签: c++

以下代码无法编译,说“错误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;
}

4 个答案:

答案 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函数是不是更容易,以避免混淆两个具有相同名称但访问权限不同的函数。