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

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

override-функция, она уже virual? [D5]


Ega23 ©   (2005-11-23 10:56:00) 

Вот код:

type
TFirstClass=class
  public
    procedure A; virtual;
 end;

TSecondClass=class(TFirstClass)
  public
    procedure A; override;
 end;

TThirdClass=class(TSecondClass)
  public
    procedure A; override;
 end;

{ TFirstClass }

procedure TFirstClass.A;
begin

end;

{ TSecondClass }

procedure TSecondClass.A;
begin
 inherited;

end;

{ TThirdClass }

procedure TThirdClass.A;
begin
 inherited;

end;



Вопрос первый. Обязательно ли указывать virtual для TSecondClass.A в описании класса? Или она уже по-умолчанию virtual?

Вопрос второй. В процедуре TThirdClass.A мне нужно выполнить наследуемый код, но не TSecondClass.A, а TFirstClass.A. Т.е. наследный код не "родителя", а "деда".
Возможен ли такой код, вместо inherited:

procedure TThirdClass.A;
begin
 TFirstClass(Self).A;

end;


?


GuAV   (2005-11-23 17:32:00) [1]


>Если это не пример, то правильнее метод объявить так
>    procedure A; virtual; adstract;

Не всегда, у TObject например несколько пустых методов.


Ega23   (2005-11-23 17:01:00) [2]


> Если это не пример, то правильнее метод объявить так


Это пример. Считается, что в каждой процедуре есть какой-то свой код. Кроме inherited-вызова.
Виноват, надо было сразу написать.


evvcom   (2005-11-23 15:29:00) [3]


> Если это не пример, то правильнее метод объявить так
>    procedure A; virtual; adstract;

Иногда да, может даже в большинстве случаев, но не всегда.


Anatoly Podgoretsky   (2005-11-23 15:23:00) [4]

procedure TFirstClass.A;
begin

end;

Если это не пример, то правильнее метод объявить так
   procedure A; virtual; adstract;


jack128   (2005-11-23 14:33:00) [5]

Представь что будет если метод TGrandPa.Func вызывает другие виртуальные методы.  Что будет в варианте MBo ? А в моем ??


Fay   (2005-11-23 14:28:00) [6]

2 jack128 ©   (23.11.05 14:22) [12]
Что такое "катастрофические различия"?


jack128   (2005-11-23 14:22:00) [7]

MBo ©   (23.11.05 13:16) [10]
Или вот так:

begin
Pointer(Pointer(Self)^) := TGrandPaClass;
try
  Result := Func;
finally
  Pointer(Pointer(Self)^) := TMeClass;
end
end;

Причем различия при выполнении твоего и моего варианта могут быть катастрафические..


Ega23   (2005-11-23 13:48:00) [8]


> MBo ©   (23.11.05 13:16) [10]


О! Вот это крайне любопытно! Спасибо!


MBo   (2005-11-23 13:16:00) [9]

>Ega23
Деда и выше можно вызвать через TMethod

type
 ObjFunc = function: string of object;
var
 M: TMethod;
begin
 M.Code := @TGrandPa.Func;
 M.Data := Self;
 Result := ObjFunc(M);


Ega23   (2005-11-23 12:39:00) [10]

Извратился следующим образом:
Код в TSecond.A (после inherited) вынес в виртуальную процедуру.
В TThird перегрузил её с пустым обработчиком.

Изврат. Но работает.  :-)


Ega23   (2005-11-23 11:38:00) [11]


> Странно слышать от Вас такой вопрос.


Дык у меня голубого значка нету...   :о)


> Причем главный вывод был - неверная структура классов.


Это я согласен. Просто не хочется уже готовую структуру перелопачивать...

Ладно, как сделать я более-менее понял.
Всем большое спасибо!


Sandman29   (2005-11-23 11:29:00) [12]

Fay ©   (23.11.05 11:15) [4]

Причем главный вывод был - неверная структура классов.


TUser   (2005-11-23 11:22:00) [13]

> Вызов метода "деда" уже пару раз обсуждался, но у меня не сохранилось. М.б. у кого есть...

А чего там обсуждать - невиртуальный можно вызвать легко с помощью приведения типов. А виртуальные - это уже извините, можно так, как я написал в [2].


begin...end   (2005-11-23 11:20:00) [14]

> Ega23 ©   (23.11.05 10:56)

> A мне нужно выполнить наследуемый код, но не TSecondClass.A,
> а TFirstClass.A. Т.е. наследный код не "родителя", а "деда".

Поскольку речь идёт о виртуальном методе, можно временно заменить ссылку на таблицу виртуальных методов.


Fay   (2005-11-23 11:15:00) [15]

2 Ega23 ©   (23.11.05 10:56)
Вызов метода "деда" уже пару раз обсуждался, но у меня не сохранилось. М.б. у кого есть...


clickmaker   (2005-11-23 11:15:00) [16]

вроде как в Оbj Pascal выше inherited не подняться


TUser   (2005-11-23 11:15:00) [17]

1. Нет, не обязательно. По крайней мере, в VCL почти никогда не указывается.

2. Нет, получится Stack Overflow, т.к. метод виртуальный и будет вызываться именно тот, который прописан в таблице виртуальных методов. Приведение типов не спасет - если очень надо, то пиши в TSecondClass обертку вокруг TFirstClass.A.


Fay   (2005-11-23 11:14:00) [18]

2 Ega23 ©   (23.11.05 10:56)
1) Если override, значит "виртуальность" как у перекрываемого.

2) TFirstClass(Self).A;вместо inheritedне прокатит. Странно слышать от Вас такой вопрос.


Наверх

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