ATL 2.1 has been optimized for the Visual C++ 5.0 compiler. In particular, you should be aware that many ATL classes are declared with the ATL_NO_VTABLE
macro:
class ATL_NO_VTABLE CComControl
{
...
};
ATL defines ATL_NO_VTABLE
as follows:
#ifdef _ATL_DISABLE_NO_VTABLE
#define ATL_NO_VTABLE
#else
#define ATL_NO_VTABLE __declspec(novtable)
#endif
If _ATL_DISABLE_NO_VTABLE
is not defined, the ATL_NO_VTABLE
macro expands to declspec(novtable)
. When declspec(novtable)
is used in a class declaration, it prevents the vtable pointer from being initialized in the class's constructor and destructor. The linker can thus eliminate the vtable and all the functions pointed to by the vtable, provided the most-derived class (usually CComObject, CComAggObject, or CComPolyObject) does not use declspec(novtable)
and will thus initialize the vtable pointer correctly.
By default, the ATL Object Wizard will generate new classes with the ATL_NO_VTABLE
macro. As previously described, the declspec(novtable)
attribute should only be used with base classes that are not directly creatable. Further, it is unsafe to call virtual functions from the constructor of any object that uses declspec(novtable)
. You should move any such calls to the FinalConstruct method.
If you are unsure whether you should use the declspec(novtable)
attribute, you can remove the ATL_NO_VTABLE
macro from any class definition or you globally disable it by specifying #define _ATL_DISABLE_NO_VTABLE
in stdafx.h, before all other ATL header files are included.