ATL プロジェクトのコンパイラ最適化の指定

既定では、ATL コントロール ウィザードによって、次のように、ATL_NO_VTABLE マクロで新しいクラスが生成されます。

class ATL_NO_VTABLE CProjName
{
...
};

_ATL_NO_VTABLE は ATL で次のように定義されています。

#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) は、直接作成することができない基底クラスでのみ使用する必要があります。 プロジェクトの最派生クラス (通常は CComObjectCComAggObject、または CComPolyObject) は vtable ポインターをプロジェクト用に初期化するので、このクラスで declspec(novtable) を使用しないでください。

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 プロジェクトの既定の構成