为 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_NO_VTABLE 宏,或者你可以通过指定全局禁用它

#define _ATL_DISABLE_NO_VTABLE

在 pch.h 中(Visual Studio 2017 及更早版本中的 stdafx.h)中,在包含所有其他 ATL 头文件之前。

另请参阅

ATL 项目向导
Visual Studio 中的 C++ 项目类型
使用 ATL 和 C 运行时代码进行编程
ATL COM 对象基础知识
novtable
默认 ATL 项目配置