【问题标题】:C++ forbid overwriting a virtual functionC++禁止覆盖虚函数
【发布时间】:2011-08-24 14:42:53
【问题描述】:

我使用库中的 A 类,并希望通过自己的 B 类为其添加一些功能。 B 类的用户应该从它派生,就像他从 A 类派生一样。

class A {
    public:
        virtual void func1()=0;
        virtual void func2()=0;
        ...
}
class B: public A {
    public:
        virtual void func1() {...}
}

所以如果有人创建了一个从 B 派生的类 C,他应该必须实现 func2:

class C: public B {
    public:
        virtual void func2() {...}
}

对于我的应用程序来说非常重要的是,C 类不会覆盖 func1,消除 B::func1()。

有没有办法禁止 B 的所有子类覆盖这个虚函数?如果不是在纯 C++ 中,当这个函数被覆盖时,boost MPL 中是否有一些东西会引发编译器错误?

【问题讨论】:

  • 是否存在A 的子类应该覆盖func2 的情况,如果没有,为什么它是虚拟的?
  • 不要认为那是可能的。因为当new C'ing 一个新的 ponter 时,编译器会尝试将它设置为在最派生的类中运行。停在派生链的中间会破坏虚函数的意图。
  • 我假设您的意思是覆盖,而不是覆盖?为什么不覆盖B::func1 对您很重要?
  • 您能否详细说明为什么它如此重要?我看到很多人要求这样做,但从未见过不能防止 maciavelli 案例的用例。
  • GCC 在 4.7 中添加了新的 final 关键字。

标签: c++ boost boost-mpl


【解决方案1】:

不,这在当前版本的 C++(即 C++03)中是不可能的。即将推出的 C++11 标准将包含上下文关键字 final,这将使这成为可能:

// C++11 only: indicates that the function cannot be overridden in a subclass
virtual void MemberFunction() final { ... }

Microsoft Visual C++ 编译器还包含关键字 sealed 作为扩展,其功能类似于 C++11 关键字 final,但这仅适用于 Microsoft 的编译器。

【讨论】:

  • 这不是真正的关键字,而是上下文关键字,对吧?也就是说,我仍然可以使用final作为标识符吗?
  • sealed 不是 Microsoft 对 C++ 的扩展,此关键字是 C++\CLI 的一部分,严格来说,它是一种单独的语言。
  • @Kirill:是的。请参阅我链接到的文档:“sealed 在编译本机目标时也有效(没有/clr)。”
  • @Adam Rosenfield,我现在看到了。不知道它可以在原生 C++ 中使用。
【解决方案2】:

不在 C++03 中,但 C++0x 提供了特殊的“最终”标识符来禁止这样做:

http://en.wikipedia.org/wiki/C++0x#Explicit_overrides_and_final

【讨论】:

  • 这不是Java最初做的吗? (我的上帝,我发现了一些关于 Java 的东西,我真的喜欢!)
  • @YellPika 我不知道“最初”,但是当我看到它时我想到的第一件事是 - “哦 - 就像 Java!” (所以你在好公司;))
【解决方案3】:

没有。在 C++03 中,您不能阻止派生类覆盖基类的1 个虚函数。但是,基类可以强制派生(非抽象)类提供虚函数的实现(在这种情况下,虚函数实际上是纯虚函数)。

1.正确的术语是覆盖,而不是覆盖。

【讨论】:

    猜你喜欢
    • 2015-06-17
    • 2020-08-21
    • 1970-01-01
    • 2014-05-22
    • 2013-10-04
    • 2010-10-04
    • 2013-01-16
    • 2021-09-30
    • 2015-12-15
    相关资源
    最近更新 更多