纯虚拟类上的DECLSPEC_NOVTABLE?

问题描述 投票:0回答:2

这可能是习惯性的编程冗余。我注意到标头中定义的一堆接口上有 DECLSPEC_NOVTABLE ( __declspec(novtable) ):

struct DECLSPEC_NOVTABLE IStuff : public IObject
{
    virtual method1 () = 0;
    virtual method2 () = 0;
};

关于这个 __declspec 扩展属性的 MS 文档说,添加这个家伙将删除构造函数和析构函数 vtable 条目,从而导致“代码大小显着减少”(因为 vtable 将被完全删除)。

这对我来说没有多大意义。这些家伙是纯虚拟的,为什么编译器不默认这样做?

文章还说,如果您这样做,然后尝试实例化其中一项,您将遇到运行时访问冲突。但是当我用一些编译器(带或不带 __declspec 扩展)尝试这个时,它们不会编译(正如我所期望的)。

所以我想总结一下:

  • 无论纯虚拟接口,编译器都会删除 vtable,还是我在这里错过了一些基本的东西?
  • MSDN 文章谈论的是什么?
c++ visual-c++ msdn pure-virtual
2个回答
3
投票

编译器删除了对 vtable 的“唯一引用”,这本来是在类的构造过程中进行的。因此,链接器可以优化它,因为代码中不再引用它。 另外,我养成了将空构造函数声明为

protected

的习惯,并使用 Microsoft 的扩展

abstract
关键字,以避免运行时的访问冲突。这样,编译器可以在编译时捕获问题(因为只有基类可以通过受保护的构造函数实例化接口)。派生类当然会在
its
构造期间填充 vtable。


2
投票

© www.soinside.com 2019 - 2024. All rights reserved.