为什么 C++ 禁止私有继承 final class?

Why does C++ forbid private inheritance of a final class?

C++11 向 C++ 引入了 final 关键字。

它可以在虚拟方法class上使用。

声明 class final 禁止 任何类型的继承:public,受保护和私有。

struct A final {
};

class B: private A {
};

 error: base 'A' ^ is marked 'final'

虽然禁止 public 继承是合理的(例如,如果我的 class 没有虚拟析构函数,或出于其他原因),我为什么要禁止私有继承?

可能是如果 final 禁止 仅 public 继承 ,那么 std::string 和它在 std 中的其他朋友将是 final -- 他们应该 -- 因为没有虚拟析构函数?

编辑:

Howard Hinnant 已经回答了 Why the standard containers are not final 但仍然有理由声明 class final 但允许私有继承。

继承就是继承。可访问性与它正交。它仅防止 静态地 将派生 class 视为基础,超出派生 class 的范围。在运行时间没有区别,如果允许私有继承,你可以这样写:

struct C {
    virtual void foo() {}
};

struct A final : C {
    virtual void foo() {}
};

void baz(A& ref) { ref.foo(); }

class B: private A {
   virtual void foo() {}
   void bar() {
       baz(*this);
   }
};

私有继承不会阻止您使用 运行 时间多态性。如果final是为了完全防止进一步覆盖,那么私有继承必须包含在禁止中。

除了 Story Teller 所说的之外,考虑 引入 final 的原因:它应该有助于优化。

当一个class是final,并且你有一个指向它的指针,编译器可以证明你正在调用哪个成员函数,即使是 virtual。如果 class 不是 final,该指针实际上可能是指向某个派生的 class 的指针,可以想象它可以覆盖 virtual 方法,强制执行完整的动态 vtable 查找。

不管是否继承private,总是可以创建一个base-class指针。在 private 继承的情况下,创建这个 base-class 指针将限于派生 class、派生 class 以及派生 class 的任何基类=29=],这仍然比优化器可用于做出决定的代码多。因此,仅禁止 all 继承允许进行虚拟调用优化。