【问题标题】:Can I forbid calling private member of derived class from base?我可以禁止从基类调用派生类的私有成员吗?
【发布时间】:2021-03-08 03:30:15
【问题描述】:

我有这个代码:

struct A {
  virtual void f() {}
};
struct B: A {
 private:
  void f() override {}
};
...
B b;
A& a = b;
a.f();

当然,它会从B 调用f(),因为在编译时会检查私有,但在运行时选择虚函数版本。这种情况下可以禁止f()打电话吗?

【问题讨论】:

  • 似乎是一个设计缺陷。如果您不能在A 中调用f,则它应该是私有的,或者在A 中根本不存在。
  • 是的。使函数成为非虚拟函数。

标签: c++ c++11 inheritance virtual private


【解决方案1】:

没有。当您在 A 引用上调用 f() 时,会在 A 上检查访问规则。你不能指望编译器检查B 的规则,因为它不一定知道a 的类型是B

来自cppreference

在调用点使用用于表示调用成员函数的对象的表达式类型检查虚函数名称的访问规则。最终覆盖者的访问被忽略:

struct B { virtual int f(); }; // f is public in B
 
class D : public B { private: int f(); }; // f is private in D
 
void f() {
  D d;
  B& b = d;
  b.f(); // OK: B::f is public, D::f is invoked even though it's private
  d.f(); // error: D::f is private
}

您的代码不应该依赖于此。在我看来,给定方法的访问说明符应该在整个类层次结构中保持一致。

【讨论】:

    猜你喜欢
    • 2012-10-29
    • 1970-01-01
    • 2021-11-15
    • 2017-04-14
    • 1970-01-01
    • 2014-04-30
    • 2017-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多