ради интереса, написал кусок кода. интересен результат выполнения. Код (Text): class ca { public: ca() {}; virtual ~ca() {}; virtual int f() = 0; virtual int g() = 0; }; class cx : public ca { public: cx() {}; ~cx() {}; virtual int f() { DWORD old_protect; void **p = *(void***)this; VirtualProtect(p, 2 * sizeof(void*), PAGE_EXECUTE_READWRITE, &old_protect); p[1] = p[0]; return 0; } virtual int g() { return 2; } }; void Main() { cx x1, x2; x1.f(); x2.g(); ca *p_x1, *p_x2; p_x1 = new cx; p_x2 = new cx; p_x1->f(); p_x2->g(); } x1.f(); x2.g(); - вызовутся f и g. p_x1->f(); p_x2->g(); - 2 раза вызовется f.
Автор решил похвастаться умением манипулировать с vtable и функцией VirtualProtect) Хотя умение весьма хреновое, судя по выставленному праву EXECUTE. А вопроса не видно
интересно что в первом случае метод вызывается через vftable, во втором - без неё. это где-то деклариовано?
Дык у тебя объекты создаются на стеке в первом случае, а во втором динамически. В любой книге по С++.
а если vftable находится в секции кода? я вообще к тому, насколько можно надеяться на перехват методов по подмене адресов в vftable?
Ровно наоборот. А декларировано - самим языком С++ Ну если класс представляет собой какой-то интерфейс и его объекты будут использоваться исключительно по указателю, тогда, наверное, можно.
Ну так естественно, если компилятор знает уже во время компиляции, какя именно функция будет вызвана, зачем использовать таблицу виртуальных функций?
Если компилятор уверен в типе, то вызов через vtbl не оптимально. Код (Text): cx x1; x1.g(); //уверен ((cx*)&x1)->g(); //уверен ((ca*)&x1)->g(); //не уверен, вызов через vtbl. Хотя это больше компиляторные особенности. Главное что работает правильно. А код в первом посту по-моему не верный. В vtbl первым идёт указатель на деструктор, а присваивание p[1] = p[0];
то есть получается, что gcc вполне может скомпилить иначе? создание vftable вообще хоть где-нибудь в спецификации С++ декларировано?
В Стандарте С++ намёков на таблицы виртуальных функций нет. Структура VTbl VC++ гарантируется спецификацией ABI COM. Указатели располагаются в таблице по порядку объявления виртуальных функций. Другим компиляторам под винду придётся делать так для совместимости. VC мог бы оптимизировать не stdcall методы но я не видел.