为 ATL 项目指定编译器优化
默认情况下,ATL 控件向导生成具有 ATL_NO_VTABLE 宏的新类,如下所示:
class ATL_NO_VTABLE CProjName
{
...
};
然后,ATL 如下定义 _ATL_NO_VTABLE:
#ifdef _ATL_DISABLE_NO_VTABLE
#define ATL_NO_VTABLE
#else
#define ATL_NO_VTABLE __declspec(novtable)
#endif
如果不定义 _ATL_DISABLE_NO_VTABLE,则 ATL_NO_VTABLE 宏扩展到 declspec(novtable)。 在类声明中使用 declspec(novtable) 可防止 vtable 指针在类构造函数和析构函数中被初始化。 当生成项目时,链接器消除 vtable 和 vtable 指向的所有函数。
ATL_NO_VTABLE(因此是 declspec(novtable))必须只能与一个无法直接创建的基类一起使用。 在项目中一定不能将 declspec(novtable) 与基本上是导出的类一起使用,因为该类(通常是 CComObject、CComAggObject 或 CComPolyObject)为项目初始化 vtable 指针。
一定不能从任何使用 declspec(novtable) 的对象的构造函数调用虚函数。 应该将那些调用移动到 FinalConstruct 方法。
如果不能确定是否应该使用 declspec(novtable) 修饰符,则在包括所有其他 ATL 头文件之前,可以从任何类定义中移除 ATL_NO_VTABLE 宏,或者可以通过在 stdafx.h 中指定
#define _ATL_DISABLE_NO_VTABLE
全局禁用 ATL_NO_VTABLE 宏。