Форум: "Основная";
Текущий архив: 2011.09.25;
Скачать: [xml.tar.bz2];
ВнизВызов inherited определённого базового класса Найти похожие ветки
← →
LightGreen (2010-02-09 12:42) [0]Такой вот вопрос... Есть иерархия классов A : B : C.
Я хочу из C вызвать метод foo(), реализованный в A.
Если я напишу inherited, то вызовется метод из B.
На C++ это делается просто A::foo(). А как это сделать в Delphi?
Спасибо.
← →
webpauk © (2010-02-09 15:10) [1]а ты не пиши inherited.
пиши A.foo()
только условие: процедура A.foo() должна быть объявлена в разделе public как class procedure.
соотв. и в классе B, и в классе С
← →
Ega23 © (2010-02-09 15:10) [2]
A(Self).Foo
← →
Ega23 © (2010-02-09 15:11) [3]
> только условие: процедура A.foo() должна быть объявлена
> в разделе public как class procedure.
> соотв. и в классе B, и в классе С
Эта... Иди книжки читай умные.
← →
webpauk © (2010-02-09 15:12) [4]TA = class
public
class procedure Foo(); dynamic;
end;
TB = class(TA)
public
class procedure Foo(); override;
end;
TC = class(TB)
public
class procedure Foo(); override;
end;
class procedure TA.Show;
begin
ShowMessage("A");
end;
class procedure TB.Show;
begin
ShowMessage("B");
end;
class procedure TC.Show;
begin
TA(Self).Show;
end;
← →
webpauk © (2010-02-09 15:13) [5]
> Ega23 © (09.02.10 15:10) [2]
>
stack overflow
← →
webpauk © (2010-02-09 15:13) [6]исправление:
class procedure TC.Show;
begin
TA.Show;
end;
← →
Ega23 © (2010-02-09 15:17) [7]
> webpauk © (09.02.10 15:13) [5]
> stack overflow
Немудрено. Обезьяна с гранатой - страшное дело.
Совет читать книги продолжает быть актуальным.
← →
Ega23 © (2010-02-09 15:18) [8]
TA = class
protected
procedure Foo;
end;
TB = class (TA)
protected
procedure Foo;
end;
TC = class (TB)
protected
procedure Foo;
public
procedure AFoo;
procedure BFoo;
procedure CFoo;
end;
{ TA }
procedure TA.Foo;
begin
ShowMessage("TA.Foo;");
end;
{ TB }
procedure TB.Foo;
begin
ShowMessage("TB.Foo;");
end;
{ TC }
procedure TC.AFoo;
begin
TA(Self).Foo;
end;
procedure TC.BFoo;
begin
inherited Foo;
end;
procedure TC.CFoo;
begin
Foo;
end;
procedure TC.Foo;
begin
ShowMessage("TC.Foo;");
end;
procedure TForm1.Button2Click(Sender: TObject);
var
t : TC;
begin
t := TC.Create;
try
t.AFoo;
t.BFoo;
t.CFoo;
finally
t.Free;
end;
end;
← →
jack128_ (2010-02-09 18:13) [9]
> LightGreen (09.02.10 12:42)
для НЕвируальных методов - TA(Self).Foo();
для виртуальных/димамических так просто не получится:
type
TA = class
public
procedure Foo(); dynamic;
end;
TAClass = class of TA;
TB = class(TA)
public
procedure Foo(); override;
end;
TC = class(TB)
public
procedure Foo(); override;
end;
procedure TA.Foo;
begin
ShowMessage("A");
end;
procedure TB.Foo;
begin
ShowMessage("B");
end;
procedure TC.Foo;
type
TObjectProcedure = procedure of object;
var
M: TMethod;
begin
M.Code := @TA.Foo;
M.Data := Self;
TObjectProcedure(M)();
end;
procedure TForm2.Button1Click(Sender: TObject);
begin
with TC.Create do
try
Foo;
finally
Free;
end;
end;
← →
int64 (2010-02-10 16:38) [10]LightGreen (09.02.10 12:42)
Много раз уже писалось, что необходимость сабжа:
1. (в большенстве случаев) связяна с кривой разработкой классов;
2. (в остальных случаях) можно обойтись без сабжа.
← →
LightGreen (2010-02-11 13:53) [11]Спасибо. Правда метод с TObjectProcedure работает только для public методов. Уже нашёл, как сделать для других - использовать присвоение PClass(Obj) на время вызова.
Для int64 - такие ситуации не обязательно связаны с кривым дизайном. Если используется код от разных поставщиков и менять в нём ничего нельзя, а можно только наследоваться, то этот приём может понадобиться. Тем более, что в C++ это делается элементарно. И ещё - если я вообще не вызову inherited - это тоже может что-то сломать, но язык позволяет беспрепятственно.
Ещё раз спасибо всем, кто откликнулся.
← →
KSergey © (2010-02-11 17:20) [12]> jack128_ (09.02.10 18:13) [9]
Зачем плохому учишь? :)
← →
Юрий Зотов © (2010-02-17 15:45) [13]> LightGreen (11.02.10 13:53) [11]
> использовать присвоение PClass(Obj) на время вызова.
Временная подмена ссылки на класс. Это стандарный способ вызова метода удаленного предка (да и не только предка) - но не забудьте использовать try-finally, иначе можно нахватать глюков по самое некуда.
← →
icWasya © (2010-02-17 17:26) [14]to LightGreen (11.02.10 13:53) [11]
> Тем более, что в C++ это делается элементарно ?
А вот так http://rsdn.ru/forum/cpp/3705754.1.aspx
← →
GrayFace © (2010-02-18 20:53) [15]Тогда так:
procedure TC.Foo;
type
TObjectProcedure = procedure of object;
var
M: TObjectProcedure;
class: TClass;
begin
class:= PClass(Obj)^;
PClass(Obj)^:= TA;
M:= Foo;
PClass(Obj)^:= class;
M(); // вызов производится уже с правильной ссылкой на VMT
end;
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2011.09.25;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.004 c