Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как вызвать виртуальный перекрытый метод предка?


tria ©   (2004-07-29 13:01:00) 

Tcl=Class()
procedure Met(); virtual
end;

TclChild=Class(cl)
procedure Met(); override;
end;

...

var clChild:TclChild;
   cl:Tcl;
begin
 clChild:=TclChild.Create();
 cl:=Pointer(clChild);
 cl.Met();
end;

вызовется TclChild.Met, а надо вызвать Tcl.Met.
Можно ли это сделать?


tria   (2004-07-29 18:20:00) [1]

Есть решение и такое:

Tcl=Class()
procedure Inh_Met();
procedure Met(); virtual
end;

procedure Tcl.Met();
begin
Inh_Met();
end;

TclChild=Class(Tcl)
procedure Met(); override;
end;
...

var clChild:TclChild;
begin
clChild:=TclChild.Create();
cl:=Pointer(clChild);
cl.Inh_Met();
end;

Удобство - метод один раз объявлен в предке, доступен всем потомкам.
Но это все глубоко ИМХО не штатные средства, а извороты.
Получается, что к методам предка можно доступится только в теле метода потомка, а напрямую вызвать - нельзя.


s999   (2004-07-29 17:41:00) [2]


> но я думал, может есть все-таки какая-нибудь штатная возможность...


Что-то все-таки недопонимаешь. inheritedэто и есть штатный метод. Если разжевывать то:

Tcl=Class()
procedure Met(); virtual
end;

TclChild=Class(Tcl)
procedure Met(); override;
procedure Inh_Met;
end;
...
procedure TclChild.Inh_Met();
begin
 inherited Met;
end;

...

var clChild:TclChild;
begin
clChild:=TclChild.Create();
cl.Inh_Met();
end;


Tria   (2004-07-29 17:04:00) [3]

>Гаврила ©
Дя я то согласен, и обыкновенно так и есть. Но вот возникла надобность (tria  (29.07.04 15:14) [5]). Естественно, что это можно как-то обойти, но я думал, может есть все-таки какая-нибудь штатная возможность...


Гаврила   (2004-07-29 16:47:00) [4]

Виртуальный на то и виртуальный, чтобы вызывался от того класса, экземпляр которого реально создан. Если надо, чтобы вызывался метод по типу переменной - просто не делай его виртуальным


VMcL   (2004-07-29 16:43:00) [5]

>> tria  (29.07.04 13:01)

TclChild = Class(cl)
 procedure CallParentMet; register;
 // ...
end;

// ...

procedure TclChild.CallParentMet; register;
asm
 call    Tcl.Met
end;

// ...
cl.CallParentMet;


Токмо это извращение. См. [8].


Ega23   (2004-07-29 15:31:00) [6]

Почему невозможно? Возможно. Только криво. В смысле спроектировано криво. У тебя.


tria   (2004-07-29 15:23:00) [7]

>Ega23 ©
Т.е. то, что хочу я, добиться нормальными средствами в принципе невозможно?


Ega23   (2004-07-29 15:18:00) [8]

Или заведи общий метод у предка, который не перекрывается у потомков, или пользуйся inherited в перекрытом методе у потомка.


tria   (2004-07-29 15:14:00) [9]

>Kurtevich
Нет. Так не проходит.
>TUser ©
Задача в общих чертах такая.
Есть один предок, у него два потомка.
Есть форма, в которой корректируются только общие поля (поля предка). По окончании корректировки дается процедура Assign(cl). Вот этот Assign - виртуальный метод. Если его перекрыть с директивой Override, то вызывается метод потомка, а не предка.


TUser   (2004-07-29 13:35:00) [10]

Извини, я код не прочитал. Ты после присвоения cl:=Pointer(), cl делаешь указателем на потомка, т.е. он у тебя уже типа TclChild. Зачем так путаться - не очень понятно, заведи себе столько переменнных, сколько надо.


Kurtevich   (2004-07-29 13:30:00) [11]

попробуй Tcl(cl).Met(); или (cl as Tcl).Met();


tria   (2004-07-29 13:08:00) [12]

>TUser ©
А поточнее?
В методе TclChild.Met вызов будет Inherited, а вот как из cl в примере вызвать Inherited Met?
Может я просто не знаю синтаксиса?


TUser   (2004-07-29 13:03:00) [13]

inherited? По-моему, у него нет особенностей, связанных с виртуальностью метода, хотя точно не помню.


Наверх

Титульная страница Поиск, карта сайта Написать письмо