纯虚拟类上的DECLSPEC_NOVTABLE?

时间:2009-03-12 00:58:19

标签: c++ visual-c++ msdn pure-virtual

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

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

此__declspec扩展属性的MSDN article表示添加此人将删除构造和析构函数vtable条目,从而导致“显着减小代码量”(因为vtable将被完全删除)。

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

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

所以我想总结一下:

  • 无论纯粹的虚拟接口如何,编译器都会剥离vtable,还是我错过了一些基本的东西?
  • MSDN文章在谈论什么?

2 个答案:

答案 0 :(得分:2)

编译器将仅引用删除到vtable,这可能是在构造类时。因此,链接器可以对其进行优化,因为代码中不再有引用它。

顺便说一下,我习惯于将空构造函数声明为protected,并使用Microsoft的扩展abstract关键字,以避免在运行时发生访问冲突。这样,编译器就会在编译时捕获问题(因为只有基类可以通过受保护的构造函数实例化接口)。派生类当然会在 构造期间填充vtable。

答案 1 :(得分:1)

对于一个愚蠢的编译器/链接器来说,它有点牵手。编译器不应该插入对此vtable的任何引用,因为很明显不需要这个vtable。编译器还可以通过链接器可以消除vtable的方式标记引用,但当然这更复杂。