Здравствуйте, Ivan, Вы писали:
I>Здравствуйте, NKZ, Вы писали:
NKZ>>Сам же __declspec(novtable) подавляет генерацию vtable в класcе следовательно ты не можешь вызывать виртуальные функций этого класса из производного.
I>не совсем так. или совсем не так
__declspec(novtable) действительно подавляет генерацию vtable путем удаления кода из конструкторов и деструткора, который инициализирует vptr — указатель на vtbl. Но смысл отключения vtbl совсем в другом — если известно, что экземпляр класса никогда не будет создан, то нет необходимости и в vtbl для этого класса.
I>Пример, классы для ATL-компонентов, которые генерирует визард, объявляются с ATL_NO_VTABLE, так как реально для класса CX создается экземпляр класса CComObject<CX>( он унаследован от CX ).
I>Никаких побочных эффектов от использования novtable нет — до тех пор пока не создать экземпляр класса, который объявлен с этим модификатором и вызвать виртуальную функцию.
>> Обычно ATL_NO_VTABLE ставят на последний класс в цепочке наследования.
I>Соотв-но нельзя использовать в последнем классе в цепочке наследования — максимум на предпоследнем
Пример кот. вы написали работает.
но пришел домой и пытался исполнить вот такой код:
class CWindowFactory
{
public:
virtual HWND Build(LPVOID pData) = 0;
};
class CEditorFrm2 : public CFrameWindowImpl<CEditorFrm2>, public CWindowFactory
{
public:
DECLARE_FRAME_WND_CLASS_EX(NULL, IDR_EDITORFRAME, 0, COLOR_APPWORKSPACE)
CEditorFrm2() {}
BEGIN_MSG_MAP(CEditorFrm2)
END_MSG_MAP()
virtual BOOL PreTranslateMessage(MSG* pMsg)
{
return FALSE;
}
//CWindowFactory::Build(LPVOID pData);
virtual HWND Build(LPVOID pData){return 0;}
};
/// где-то в другой ф-ии
CEditorFrm2* pFrm = new CEditorFrm2();
CWindowFactory* pwf = (CWindowFactory*)(pFrm);
delete pwf; // вот тут вылезает _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)); в файле dbgdel.cpp
что такое.. не понимаю.. =((((