【发布时间】:2013-09-22 19:34:18
【问题描述】:
我真的不明白它为什么会起作用,但下面的代码显示了一个在没有任何朋友类的情况下从世界调用私有方法的示例:
class A
{
public:
virtual void someMethod(){
std::cout << "A::someMethod";
}
};
class B : public A
{
private:
virtual void someMethod(){
std::cout << "B::someMethod";
}
};
int main(){
A* a = new B;
a->someMethod();
}
输出:
B::someMethod
这不违反C++中的封装规则吗?对我来说,这太疯狂了。继承是公有的,但派生类中的访问修饰符改为私有,因此B类中的someMethod()是私有的。所以其实在做a->someMethod(),我们就是直接从世界上调用了一个私有方法。
【问题讨论】:
-
这很愚蠢而且很糟糕,但 C++ 就是这样工作的。
-
这既不是愚蠢也不是坏事,因为这就是 polymorphism 的工作方式:
a的用户可能不知道a指向的是什么类型(动态类型*a)。a的用户可能只知道“接口”class A,并使用该接口提供的功能。这个接口的功能是public,所以是允许的。您可以使用不同的访问修饰符覆盖派生类中的函数,从而实现更灵活的设计。 -
@DyP:
private访问修饰符是个谎言。无论语义是否有用,一个方法可以声明为private,然后无论如何都可以在类外部访问这一事实是一个糟糕的设计。 -
请注意,
B b; b.someMethod();格式不正确,但B b; b.A::someMethod();格式正确。 -
@user2357112 如果我们将指向该函数的指针传递给外部,情况也是如此。
private如果您将“私有”定义为 只能从内部调用(仍然不包括指向成员函数的指针),那么这里只是一个“谎言”。我想说访问说明符仅适用于函数的 name,而不适用于函数本身(与链接一样)。 名称B::someMethod无法从外部访问。
标签: c++ inheritance polymorphism encapsulation