таблица виртуальных функций.

Тема в разделе "LANGS.C", создана пользователем maksim_, 24 сен 2009.

  1. maksim_

    maksim_ New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2009
    Сообщения:
    263
    ради интереса, написал кусок кода. интересен результат выполнения.
    Код (Text):
    1. class ca
    2. {
    3. public:
    4.     ca() {};
    5.     virtual ~ca() {};
    6.     virtual int f() = 0;
    7.     virtual int g() = 0;
    8. };
    9.  
    10. class cx :
    11.     public ca
    12. {
    13. public:
    14.     cx() {};
    15.     ~cx() {};
    16.  
    17.     virtual int f()
    18.     {
    19.         DWORD   old_protect;
    20.  
    21.         void **p = *(void***)this;
    22.  
    23.         VirtualProtect(p, 2 * sizeof(void*), PAGE_EXECUTE_READWRITE, &old_protect);
    24.  
    25.         p[1] = p[0];
    26.         return 0;
    27.     }
    28.  
    29.     virtual int g()
    30.     {
    31.         return  2;
    32.     }
    33. };
    34.  
    35. void Main()
    36. {
    37.     cx x1, x2;
    38.  
    39.     x1.f();
    40.     x2.g();
    41.  
    42.     ca *p_x1, *p_x2;
    43.  
    44.     p_x1 = new cx;
    45.     p_x2 = new cx;
    46.  
    47.     p_x1->f();
    48.     p_x2->g();
    49. }
    x1.f(); x2.g(); - вызовутся f и g. p_x1->f(); p_x2->g(); - 2 раза вызовется f.
     
  2. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    а в чем вопрос?
     
  3. W4FhLF

    W4FhLF New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2006
    Сообщения:
    1.050
    Ну затёр ты указатель на g() в vtable. Что дальше? Где сенсация?
     
  4. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Автор решил похвастаться умением манипулировать с vtable и функцией VirtualProtect)
    Хотя умение весьма хреновое, судя по выставленному праву EXECUTE.
    А вопроса не видно
     
  5. maksim_

    maksim_ New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2009
    Сообщения:
    263
    интересно что в первом случае метод вызывается через vftable, во втором - без неё. это где-то деклариовано?
     
  6. W4FhLF

    W4FhLF New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2006
    Сообщения:
    1.050
    Дык у тебя объекты создаются на стеке в первом случае, а во втором динамически.

    В любой книге по С++.
     
  7. maksim_

    maksim_ New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2009
    Сообщения:
    263
    а если vftable находится в секции кода?

    я вообще к тому, насколько можно надеяться на перехват методов по подмене адресов в vftable?
     
  8. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Ровно наоборот. А декларировано - самим языком С++ :)

    Ну если класс представляет собой какой-то интерфейс и его объекты будут использоваться исключительно по указателю, тогда, наверное, можно.
     
  9. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    также автор позабыл деаллоцировать память ;)
     
  10. maksim_

    maksim_ New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2009
    Сообщения:
    263
    с ума сойти можно. есть такое слово - пример. зачем загромождать лишним?
     
  11. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    Ну так естественно, если компилятор знает уже во время компиляции, какя именно функция будет вызвана, зачем использовать таблицу виртуальных функций?
     
  12. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Если компилятор уверен в типе, то вызов через vtbl не оптимально.
    Код (Text):
    1. cx x1;
    2. x1.g(); //уверен
    3. ((cx*)&x1)->g(); //уверен
    4. ((ca*)&x1)->g(); //не уверен, вызов через vtbl.
    Хотя это больше компиляторные особенности. Главное что работает правильно.

    А код в первом посту по-моему не верный. В vtbl первым идёт указатель на деструктор, а присваивание p[1] = p[0];
     
  13. W4FhLF

    W4FhLF New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2006
    Сообщения:
    1.050
    Да вообще никто не гарантирует структуру vtable.
     
  14. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    Никто не гарантирует, даже, что она существует. :)
     
  15. cupuyc

    cupuyc New Member

    Публикаций:
    0
    Регистрация:
    2 апр 2009
    Сообщения:
    763
    то есть получается, что gcc вполне может скомпилить иначе? создание vftable вообще хоть где-нибудь в спецификации С++ декларировано?
     
  16. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    В Стандарте С++ намёков на таблицы виртуальных функций нет. Структура VTbl VC++ гарантируется спецификацией ABI COM. Указатели располагаются в таблице по порядку объявления виртуальных функций. Другим компиляторам под винду придётся делать так для совместимости. VC мог бы оптимизировать не stdcall методы но я не видел.