这可能是习惯性的编程冗余。我注意到标头中定义的一堆接口上有 DECLSPEC_NOVTABLE ( __declspec(novtable) ):
struct DECLSPEC_NOVTABLE IStuff : public IObject
{
virtual method1 () = 0;
virtual method2 () = 0;
};
关于这个 __declspec 扩展属性的 MS 文档说,添加这个家伙将删除构造函数和析构函数 vtable 条目,从而导致“代码大小显着减少”(因为 vtable 将被完全删除)。
这对我来说没有多大意义。这些家伙是纯虚拟的,为什么编译器不默认这样做?
文章还说,如果您这样做,然后尝试实例化其中一项,您将遇到运行时访问冲突。但是当我用一些编译器(带或不带 __declspec 扩展)尝试这个时,它们不会编译(正如我所期望的)。
所以我想总结一下:
编译器删除了对 vtable 的“唯一引用”,这本来是在类的构造过程中进行的。因此,链接器可以优化它,因为代码中不再引用它。 另外,我养成了将空构造函数声明为
protected
的习惯,并使用 Microsoft 的扩展
abstract
关键字,以避免运行时的访问冲突。这样,编译器可以在编译时捕获问题(因为只有基类可以通过受保护的构造函数实例化接口)。派生类当然会在 its构造期间填充 vtable。