Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.12.18;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.48 MB
Время: 0.013 c
14-1132490094
AlexShm
2005-11-20 15:34
2005.12.18
7-я или 8-я?


14-1133096072
Kerk
2005-11-27 15:54
2005.12.18
Филиал конфы "Начинающим" у меня в мобильном...


5-1109751986
ancara
2005-03-02 11:26
2005.12.18
Компонент не ловит WM_KEYDOWN :(


3-1130580897
Leonid
2005-10-29 14:14
2005.12.18
Как расширить поле DBF-файла ?


1-1132217128
Ярослав
2005-11-17 11:45
2005.12.18
Путь до файлу службы





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский