RU/2: Форум. Общение пользователей и разработчиков OS/2 (eCS). : Может я не прав, но..


Список сообщений | Написать новое | Ответить на сообщение | Домой Поиск:
Предыдущее сообщение | Следующее сообщение
From : Slavik Gnatenko, 2:467/99
To : Юрий Пронякин
Subj : Может я не прав, но..

> Совершенно верно. А теперь рассмотрим случай, когда есть глубокая иерархия классов и есть объект одного из глубинных классов. Для простоты рассмотрим вызов метода этого объекта, который не перекрыт нигде в иерархии (т.е. на всех уровнях используется метод корневого класса). Каакой код мы имеем в этом случае? Находится адрес таблицы методов класса нашего объекта и из неё по индексу call-ом вызывается соответствующая подпрограмма (реализующая этот метод). А у ней своего кода нет, она толко то и делает, что находит таблицу методов своего родительского класса и точно таким же образом вызывает подпрограмму оттуда. Та подпрограмма, в свою очередь, проделывает в точности всё то же самое для вызова метода своего родителя и т.д. - аж до корня. Там выполняется что-то реальное, после чего начинается возврат ret-ами в то место, откуда всё и началось.

Господь с тобой.
================ test.cpp ===============
class A
{
public:
virtual void mfa();
};

void A::mfa()
{
}

class B: public A
{
public:
virtual void mfb();
};

void B::mfb()
{
}

void f()
{
B b;
b.mfa();
b.mfb();
}
==========================================

================ test.S ==================
0000 void near A::mfa():
0000 C3 ret

0001 void near B::mfb():
0001 C3 ret

0002 void near f():
0002 83 EC 04 sub esp,0x00000004
0005 C7 04 24 04 00 00 00 mov dword ptr [esp],offset void (near * const near __vftbl[])()+0x4
000C 89 E0 mov eax,esp
000E E8 00 00 00 00 call void near A::mfa()
0013 89 E0 mov eax,esp
0015 E8 00 00 00 00 call void near B::mfb()
001A 83 C4 04 add esp,0x00000004
001D C3 ret


Comdat: void (near * const near __vftbl[])() SEGMENT ANY 'DGROUP:CONST2' 0000000C bytes
0000 void (near * const near __vftbl[])():
0000 00 00 00 00 ....
0004 00 00 00 00 DD offset void near A::mfa()
0008 00 00 00 00 DD offset void near B::mfb()
==============================================
Ватком, при полностью выключеной оптимизации. Как видишь, нужная VMT определяется ещё на этапе компиляции. Хотя за Дельфи я не отвечаю. Оно зверёк забавный и всё может.


Sat 14 Jul 2007 15:01 Mozilla/5.0 (OS/2; U; Warp 4.5; en-US; rv:1.8.1.2pre) Gecko/




Programmed by Dmitri Maximovich, Dmitry I. Platonoff, Eugen Kuleshov.
25.09.99 (c) 1999, RU/2. All rights reserved.
Rewritten by Dmitry Ban. All rights ignored.