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

Вниз

override-функция, она уже virual?   Найти похожие ветки 

 
Ega23 ©   (2005-11-23 10:56) [0]

Вот код:

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;


?


 
Fay ©   (2005-11-23 11:14) [1]

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

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


 
TUser ©   (2005-11-23 11:15) [2]

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

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


 
clickmaker ©   (2005-11-23 11:15) [3]

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


 
Fay ©   (2005-11-23 11:15) [4]

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


 
begin...end ©   (2005-11-23 11:20) [5]

> Ega23 ©   (23.11.05 10:56)

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

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


 
TUser ©   (2005-11-23 11:22) [6]

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

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


 
Sandman29 ©   (2005-11-23 11:29) [7]

Fay ©   (23.11.05 11:15) [4]

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


 
Ega23 ©   (2005-11-23 11:38) [8]


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


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


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


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

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


 
Ega23 ©   (2005-11-23 12:39) [9]

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

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


 
MBo ©   (2005-11-23 13:16) [10]

>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 13:48) [11]


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


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


 
jack128 ©   (2005-11-23 14:22) [12]

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

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

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


 
Fay ©   (2005-11-23 14:28) [13]

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


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

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


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

procedure TFirstClass.A;
begin

end;

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


 
evvcom ©   (2005-11-23 15:29) [16]


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

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


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


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


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


 
GuAV ©   (2005-11-23 17:32) [18]


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

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



Страницы: 1 вся ветка

Текущий архив: 2005.12.18;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.045 c
3-1131003784
gusev
2005-11-03 10:43
2005.12.18
Ошибка в запросе по дате и времени


3-1130856634
Mouse_Rat
2005-11-01 17:50
2005.12.18
Backup таблицы из FireBird


14-1132779127
ArtemESC
2005-11-23 23:52
2005.12.18
Колонки неработают...


1-1132068468
TStas
2005-11-15 18:27
2005.12.18
Как лучше сделать электронный бланк


8-1121117343
АСК1
2005-07-12 01:29
2005.12.18
pfDevice - это сколько байт на пиксель в TBitMap ?