Главная страница
    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.48 MB
Время: 0.012 c
4-1129903440
psa247
2005-10-21 18:04
2005.12.18
Убрать кнопку с панели задач в Run_time !


1-1132911148
_dimka
2005-11-25 12:32
2005.12.18
закрытие MDI Форм


14-1132694308
Богдан1024
2005-11-23 00:18
2005.12.18
Файлы *.HXI


6-1126005509
Skat
2005-09-06 15:18
2005.12.18
Проблемы связи


3-1130853165
Goast
2005-11-01 16:52
2005.12.18
Репликация interBase





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский