这可能是习惯性的编程冗余。我注意到在头文件中定义的一堆接口上有DECLSPEC_NOVTABLE(__ declspec(novtable)):
struct DECLSPEC_NOVTABLE IStuff : public IObject
{
virtual method1 () = 0;
virtual method2 () = 0;
};
此__declspec扩展属性的MSDN article表示添加此人将删除构造和析构函数vtable条目,从而导致“显着减小代码量”(因为vtable将被完全删除)。
这对我来说没什么意义。这些人是纯虚拟的,为什么编译器默认不这样做呢?
文章还说,如果你这样做,然后尝试实例化其中一个,你将得到一个运行时访问冲突。但是当我尝试使用一些编译器(带或不带__declspec扩展)时,它们不会编译(正如我预期的那样)。
所以我想总结一下:
答案 0 :(得分:2)
编译器将仅引用删除到vtable,这可能是在构造类时。因此,链接器可以对其进行优化,因为代码中不再有引用它。
顺便说一下,我习惯于将空构造函数声明为protected
,并使用Microsoft的扩展abstract
关键字,以避免在运行时发生访问冲突。这样,编译器就会在编译时捕获问题(因为只有基类可以通过受保护的构造函数实例化接口)。派生类当然会在 构造期间填充vtable。
答案 1 :(得分:1)
对于一个愚蠢的编译器/链接器来说,它有点牵手。编译器不应该插入对此vtable的任何引用,因为很明显不需要这个vtable。编译器还可以通过链接器可以消除vtable的方式标记引用,但当然这更复杂。