Настройка оптимизации компилятора для проекта 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 (stdafx.h в Visual Studio 2017 и более ранних версиях), прежде чем включены все другие файлы заголовков ATL.
См. также
Мастер проектов ATL
Типы проектов C++ в Visual Studio
Программирование с использованием ATL и кода среды выполнения C
Основы COM-объектов ATL
novtable
Конфигурации проектов ATL по умолчанию