Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2011.09.25;
Скачать: CL | DM;

Вниз

Вызов 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;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.009 c
2-1307440318
uniken1
2011-06-07 13:51
2011.09.25
захват выводв SSH2


15-1306050365
Virgo_Style
2011-05-22 11:46
2011.09.25
WinCGI+Firebird. Искать хостинг или переписать все нафиг?


15-1306784454
chum
2011-05-30 23:40
2011.09.25
возможно ли послать PCL-команду на принтер HP LJ1018


1-1267021784
nokla user
2010-02-24 17:29
2011.09.25
Окно копирования windows


15-1306581550
Smile
2011-05-28 15:19
2011.09.25
Красивое видео с цирковым номерм баланса