Форум: "Основная";
Текущий архив: 2006.10.01;
Скачать: [xml.tar.bz2];
ВнизВызов метода предка класса минуя непосредственного предка. Найти похожие ветки
← →
harisma (2006-08-17 14:03) [0]Вопрос такой: Есть 3 класса А - В - С. В унаследован от А, С унаследован от В. В классах есть перекрытый метод. Как мне из этого метода в классе С вызвать этот же метод класса А? типа как делается inherited для вызова метода непосредственного предка?
← →
begin...end © (2006-08-17 14:07) [1]Статический или виртуальный?
← →
harisma (2006-08-17 14:10) [2]виртуальный
← →
tesseract © (2006-08-17 14:13) [3]A(ыуда).CallMethod - должен вызваться именно метод класса А.
← →
harisma (2006-08-17 14:15) [4]Спасибо. А еще варианты есть?
← →
default © (2006-08-17 14:18) [5]A = class
procedure F; virtual;
end;
B = class(A)
procedure F; override;
end;
C = class(B)
procedure F; override;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure A.F;
begin
ShowMessage("A.F");
end;
procedure B.F;
begin
ShowMessage("B.F");
end;
procedure C.F;
var
P: procedure of object;
begin
TMethod(P).Code := @A.F;
TMethod(P).Data := Self;
P;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
O: C;
begin
O := C.Create;
O.F;
end;
как вариант
← →
begin...end © (2006-08-17 14:21) [6]Заменить ссылку на VMT, вызвать метод, восстановить ссылку.
← →
default © (2006-08-17 14:22) [7]tesseract © (17.08.06 14:13) [3]
так будет переполнение стека из-за бесконечной рекурсии
← →
tesseract © (2006-08-17 14:22) [8]
> tesseract © (17.08.06 14:13) [3]
очепятался. там self.
← →
Ketmar © (2006-08-17 14:24) [9]> [4] harisma (17.08.06 14:15)
а чем этот не нравится? есть конечно, и не один, ивсе через анус. но зачем?
← →
default © (2006-08-17 14:25) [10]Ketmar © (17.08.06 14:24) [9]
это неверный способ([4])
← →
default © (2006-08-17 14:25) [11][3] то есть...
← →
tesseract © (2006-08-17 14:26) [12]
> default © (17.08.06 14:22) [7]
Почему? Ведь должен вызваться метод родителя, а не потомка.
← →
default © (2006-08-17 14:27) [13]tesseract © (17.08.06 14:26) [12]
такой способ прокатит только для статических методов
с виртуальными такое не прокатит
← →
begin...end © (2006-08-17 14:31) [14]> Ketmar © (17.08.06 14:24) [9]
Смело...
← →
Ketmar © (2006-08-17 14:34) [15]> [13] default © (17.08.06 14:27)
пардон, не вчитался. снова извиняюсь.
что-то я сегодня слова теряю...
← →
tesseract © (2006-08-17 14:36) [16]
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type Tclass1= class
public
procedure ShowMessage; virtual;
end;
type Tclass2= class(Tclass1)
public
procedure ShowMessage; virtual;
end;
type Tclass3= class(Tclass2)
public
procedure ShowMessage; virtual;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ Tclass1 }
procedure Tclass1.ShowMessage;
begin
MessageBox(0, "class 1", " no error", MB_ICONWARNING or MB_OK);
end;
procedure Tclass2.ShowMessage;
begin
MessageBox(0, "class 2", " no error", MB_ICONWARNING or MB_OK);
end;
procedure Tclass3.ShowMessage;
begin
Tclass1(self).ShowMessage;
end;
procedure TForm1.Button1Click(Sender: TObject);
var c1: Tclass1;
c2: Tclass2;
c3: Tclass3;
begin
c1:=tclass1.Create;
c2:=tclass2.Create;
c3:=tclass3.Create;
c3.ShowMessage;
c1.Free;
c2.Free;
c3.Free;
end;
end.
Вроде работает, но как там с полями/другими методами будет не уверен.
← →
tesseract © (2006-08-17 14:37) [17]
procedure Tclass3.ShowMessage;
begin
Tclass1(self).ShowMessage;
inherited ShowMessage;
MessageBox(0, "class 3", " no error", MB_ICONWARNING or MB_OK);
end;
так нагляднее, в D7 работает.
← →
begin...end © (2006-08-17 14:39) [18]Пример к [6]:
var
ObjC: C;
TempClass: TClass;
begin
...
TempClass := ObjC.ClassType;
try
PPointer(ObjC)^ := ObjC.ClassParent.ClassParent;
ObjC.P;
finally
PPointer(ObjC)^ := TempClass;
end;
...
end
← →
default © (2006-08-17 14:42) [19]tesseract © (17.08.06 14:37) [17]
блин, траблы у тебя с объектной моделью...
ты везде virtual пишешь - это значит новый метод, а не перекрытие старого...
тогда, конечно, приведение будет работать...
← →
harisma (2006-08-17 14:44) [20]У меня этот метод объявлен как virtual только в классе А. В классах В и С он обїявляется как override.
← →
begin...end © (2006-08-17 14:44) [21]В [18] P -- это имя метода, конечно.
← →
tesseract © (2006-08-17 14:44) [22]
> default © (17.08.06 14:42) [19]
насчёт этого я как раз в курсе, а что это не решение [0] ?
← →
default © (2006-08-17 14:47) [23]harisma (17.08.06 14:44) [20]
дали уже два решения [5] и [18]
tesseract © (17.08.06 14:44) [22]
[20]
← →
default © (2006-08-17 14:56) [24]во всех(думаю нет ислючений) ООП языках, есть специальный синтаксис только для вызова метода предка
стоит задумать о архитектуре классов, прежде чем городить огород из подобных "финтов" - максимум простоты и логичности!
← →
default © (2006-08-17 14:57) [25]непосредственного предка
← →
default © (2006-08-17 15:03) [26]важно понять, что эти "финты" всего лишь заплаты для огрех проектирования
(скорее всего)
свою "крутость" в них показывать на самом деле не круто
← →
WondeRu © (2006-08-17 15:08) [27]вот в своем проекте нашел:
иерархия такая
A-B-C
type
TDrawProj = procedure (Sender: TObject; const SelectRender: Boolean = False);
.....
procedure C.Draw(const SelectRender: Boolean = False);
begin
TDrawProj(@A.Draw)(Self, SelectRender);
....
end;
← →
tesseract © (2006-08-18 10:45) [28]
> default © (17.08.06 15:03) [26]
Я никогда свою крутость не показывал. Имхо как раз перезаписывание VMT - ошибка проектирования. Чистое ИМХО.
← →
default © (2006-08-18 11:22) [29]tesseract © (18.08.06 10:45) [28]
я ни в коем случае ни на кого не намекал говоря про крутость!
просто указал, что стоит задуматься автору сабжа над архитектурой класса прежде чем использовать выданные решения
подобные решения скорее как задачка для какого-нибудь собеседования, чем на реальное применение
← →
default © (2006-08-18 11:24) [30]WondeRu © (17.08.06 15:08) [27]
так делать в общем случае нельзя
вызывать надо процедуру объекта, а не обычную
в данном случае просто повезло, что работает
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2006.10.01;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.012 c