【问题标题】:Deleting virtual functions in C++0x在 C++0x 中删除虚函数
【发布时间】:2011-04-24 00:43:51
【问题描述】:

不清楚如果我在 C++0x 中删除虚方法会发生什么:

 virtual int derive_func() = delete;

这是否意味着这个类以及从它继承的所有东西都不能定义/实现derive_func() 方法?还是这是非法/编译错误?

【问题讨论】:

  • @GMan 我同意这可能没有合理的理由,但该提案似乎明确允许它。
  • @flynt:糟糕,抱歉。 :) 删除了你。
  • 是否会强制创建 RTTI。当前 C++ 中的等价物是有一个空的虚拟析构函数?

标签: c++ c++11 virtual-functions deleted-functions


【解决方案1】:

flownt got it right,但我要指出的是,在最终的 C++11 草案(N3337)中,对应的语言已经移到第 10.3#16 节:

具有已删除定义的函数不应覆盖函数 没有删除的定义。同样,一个函数 没有删除的定义不应覆盖具有 已删除的定义。2

对我来说(第 8.4.3#1 节)似乎相当清楚,已删除的定义实际上算作定义,实际上是一个内联定义,这意味着删除的定义满足 10.3#11:

类中声明的虚函数应被定义或声明 纯属该类,或两者兼而有之;但不需要诊断。2

但是,当前的实现似乎不同意。这是我的测试用例:

struct Base {
    virtual void bar();
    virtual void foo() = delete;
};

void Base::bar() { }  // a definition of the first non-inline virtual function
int main() { Base b; }
  • Clang 生成一个不可链接的程序:Base::fooBase 的 vtable 中被提及。如果你交换foobar 的顺序,链接器会抱怨整个vtable 丢失(因为Clang 认为foo 是一个没有定义的非内联函数)。 I filed this as a bug;我们会看看开发者的想法。

  • GCC 在创建 vtable 时抱怨在翻译单元末尾“使用”foo;但无论foobar 的顺序如何,它都正确地将bar 识别为第一个非内联虚成员函数。

【讨论】:

    【解决方案2】:

    http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2326.html#delete A deleted virtual function may not override a non-deleted virtual function and vice-versa. 意味着它非常无用(至少我读过它)唯一有效的用途是:

    struct A{
         virtual void b() = delete;
    };
    struct B:A{
         virtual void b() = delete;
    };
    

    这是完全没用的,因为函数永远不能被调用。对于非虚函数,使用更合理

    编辑 要完全清楚,这是唯一可能的关系,孩子可能不会实现,您可能不会删除未删除的继承虚拟。

    【讨论】:

    • 是否强制存储 RTTI 信息?
    • 所以这就像我删除的答案?
    • @Klaim:我将如何查看您删除的答案?
    • 复制/粘贴:我的理解(这可能是错误的,但如果是,请告诉我们)是:如果它是一个基类,它与声明一个虚拟纯函数完全相同(使用=0);如果它是一个子类并且 deriv_func() 已经被声明为 virtual,这就像让子实现为空,使子类成为一个抽象类,强制该子类的子类实现函数......
    • 也许我误读了它,但正如它在答案中所代表的那样,它似乎暗示它与 =0 并不完全相同,并且 g++ 似乎证实了这一点,尽管我无法编译该示例,因为它认为我正在使用该功能(似乎是一个错误)。
    猜你喜欢
    • 2011-09-21
    • 2011-10-10
    • 1970-01-01
    • 2011-10-07
    • 1970-01-01
    • 2014-08-27
    • 1970-01-01
    • 2015-10-16
    • 1970-01-01
    相关资源
    最近更新 更多