![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
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не прокатит. Странно слышать от Вас такой вопрос.