![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Вызов метода дальнего предка
Ромик © (2002-04-23 15:02:00)Имеется следующая задача:
есть три класса связанные наследованием
type
C1 = class
procedure Method1;virtual;
end;
type
C2 = class(C1)
procedure Method1;override;
end;
type
C3 = class(C2)
procedure Method1;override;
end;
Известно, что внутри C3.Method1 можно вызвать C2.Method1
как
inherited Method1;
А вот как внутри C3.Method1 явно вызвать C1.Method1?
Игорь Шевченко (2002-04-24 12:33:00) [1]День добрый, Толик ©,
>Да и в исходниках Делфей подобных вызовов виртуальных ф-й >полным полно
> -Сделать поиск по System.pas Именно оттуда я об этот и узнал
И что же там искать ?
Я, сколько не искал, вызовов виртуальных функций таким методом не нашел :-)
И механизм виртуальных функций в Delphi реализован вполне нормально...
А писать серьезные вещи можно одинаково и на Delphi и на C++, между прочим :-))
С уважением,
Толик (2002-04-24 12:19:00) [2]to MBo ©:
>>IMHO, подобные извраты проистекают из неверного построения классовой иерархии и т.п.
- Подобные извраты проистекают из-за кривой реализации виртуальных ф-й в Делфях. Ну криво они реализованы (по сравнению с С++) и всё тут!!! Не забыли мои вопросы по поводу вызова виртуальных ф-й через указаль??? Да и вообще, на Делфях надо делать то, что они умеют лучше всего: быстро делать пользовательский интерфейс, рисовать бантики и рюшечки. А всю серьёзную логику писать на том, что к этому наиболее приспособлено (напр. тот же Borland C++ Builder или Visual C++)
to Игорь Шевченко ©:
>>Примеры готовы привести? :-)
-Сделать поиск по System.pas Именно оттуда я об этот и узнал :)
vuk (2002-04-23 22:43:00) [3]Самый правильный метод (ИМХО) - перестроить того самого предка таким образом, чтобы тот код, к которому будут обращаться потомки был вынесен в отдельный метод, а из виртуального метода было к этому отдельному методу обращение.
Adder (2002-04-23 21:52:00) [4]>А ведь в добром старом BP7 все делалось просто.
Если не надо обращаться к данным, то можно и почти как "в добром старом BP7 " сделать:
type
C1 = class
class procedure Method1; virtual;
end;
type
C2 = class(C1)
class procedure Method1; override;
end;
type
C3 = class(C2)
class procedure Method1;override;
end;
class procedure C1.Method1;
begin
writeln("Grand");
end;
class procedure C2.Method1;
begin
writeln("Dad");
end;
class procedure C3.Method1;
begin
writeln("Son");
c1.Method1;
end;
vuk (2002-04-23 19:08:00) [5]>А ведь в добром старом BP7 все делалось просто.
В старом добром BP не было методов класса. Именно тот же сакмый синтаксис используется в BP для вызовов методов предка.
А вообще поддерживаю MBo, само возникновение такой необходимости говорит о не совсем верном проектировании классов.
Бурундук (2002-04-23 18:10:00) [6]>Очень не хотелось лазить по VMT, но видно придется.
А чем тебе, собственно, не нравится метод, предложенный MBo?
Он безо всяких копаний в VMT и наиболее безопасен из
всех возможных вариантов.
Ромик (2002-04-23 17:47:00) [7]Спасибо всем откликнувшимся.
Очень не хотелось лазить по VMT, но видно придется.
Значит простых методов нет. А ведь в добром старом BP7
все делалось просто.
Игорь Шевченко (2002-04-23 17:36:00) [8]День добрый, MBo ©,
> подобные извраты проистекают из неверного построения классовой
> иерархии
Что интересно, в borland.public.delphi.objectpascal тоже так считают :-))
С уважением,
Игорь Шевченко (2002-04-23 17:34:00) [9]День добрый, Толик ©,
> Да и в исходниках Делфей подобных вызовов виртуальных ф-й
> полным полно
Примеры готовы привести? :-)
С уважением,
MBo (2002-04-23 17:32:00) [10]IMHO, подобные извраты проистекают из неверного построения классовой иерархии и т.п.
Толик (2002-04-23 17:29:00) [11]to Игорь Шевченко ©:
Ну почему же сразу никак? Очень даже как... Особенно если посмотреть хелпы по VMTOFFSET. Да и в исходниках Делфей подобных вызовов виртуальных ф-й полным полно. Короче, идея состоит в следующем: получить указатель на VMT класса предка через смещение на vmtParent (ну или использовать ф-ю ClassParent), а затем вызывать то, что лежит по адресу VMT предка + VMTOFFSET необходимой ф-и.
MBo (2002-04-23 16:26:00) [12]procedure C3.Method1;
type tproc=procedure of object;
var m:tmethod;
begin
m.code:=@c1.method1;
m.data:=self;
TProc(m);
end;
SVM (2002-04-23 16:03:00) [13]procedure C3.Method1;
var
ClassOld:TClass;
begin
ClassOld:=PClass(Self)^;
try
PClass(Self)^:=Self.ClassParent.ClassParent;
Method1;
finally
PClass(Self)^:=ClassOld;
end;
end;
Игорь Шевченко (2002-04-23 15:12:00) [14]День добрый,
Обычно, никак :-)
IMHO, можно пытаться через VMT извлекать адрес метода дедушки,
но во всех конференциях по Delphi говорится, что делать этого не стоит.
С уважением,