Форум: "Основная";
Текущий архив: 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