Форум: "Начинающим";
Текущий архив: 2014.03.23;
Скачать: [xml.tar.bz2];
ВнизВызов метода родителя Найти похожие ветки
← →
novai (2013-06-15 19:54) [0]есть 1й объект с
procedure Draw(Dest: TImg); dynamic;
есть 2й объект наследник 1го
procedure Draw(Dest: TImg); reintroduce; override;
есть 3й наследник 2го
procedure Draw(Dest: TImg); reintroduce; override;
как из 3го объекта вызвать Draw 1 объекта, а не 2!?
← →
novai (2013-06-15 20:17) [1]http://www.sql.ru/forum/290488/inherited-inherited-kak
вопрос снят
← →
Юрий Зотов © (2013-06-15 21:57) [2]Есть еще такой метод - временная подмена класса. Недостаток его в том, что он полухакерский, а достоинство в том, что таким способом можно вызвать любой метод любого класса, причем не только по линии наследования.
type
TForm1 = class(TForm)
procedure FormDblClick(Sender: TObject);
end;
TA = class
procedure Proc; virtual;
end;
TB = class(TA)
procedure Proc; override;
end;
TC = class(TB)
procedure Proc; override;
end;
procedure TA.Proc;
begin
ShowMessage("TA");
end;
procedure TB.Proc;
begin
ShowMessage("TB");
end;
procedure TC.Proc;
var
P: PPointer;
begin
P := Pointer(Self);
P^ := Pointer(TA);
try
Proc
finally
P^ := Pointer(TC);
end
end;
procedure TForm1.FormDblClick(Sender: TObject);
begin
with TC.Create do
try
Proc
finally
Free
end
end;
← →
Rouse_ © (2013-06-15 22:54) [3]
> P^ := Pointer(TA);
Юр, а ты злой.
В определенной ситуации с таким подходом VMT будет убита напрочь :)
← →
[ВладОшин] © (2013-06-16 08:41) [4]да и пусть злой )
зато прием шикарный, спасибо д.Юр!
← →
[ВладОшин] © (2013-06-16 08:59) [5]кстати, Розыч, не расскажешь в 2х словах про эти обстоятельства?
а то я намерен уже применять повсеместно )
← →
Юрий Зотов © (2013-06-16 11:53) [6]
> Rouse_ © (15.06.13 22:54) [3]
Ну, сама VMT убита не будет - лежит себе в памяти, и лежит, куда б ей деваться. Но вот ссылку на VMT в нулевом поле экземпляра потерять действительно можно, если постараться. Именно поэтому в TC.Proc и стоит try-finally.
← →
Rouse_ © (2013-06-16 12:08) [7]
> [ВладОшин] © (16.06.13 08:59) [5]
> кстати, Розыч, не расскажешь в 2х словах про эти обстоятельства?
Вызов из двух нитей.
← →
Юрий Зотов © (2013-06-16 12:23) [8]> [ВладОшин] © (16.06.13 08:59) [5]
> а то я намерен уже применять повсеместно )
Очень-очень-очень-очень НЕ советую. Подобные приемы следует применять КРАЙНЕ осторожно и лишь в исключительных случаях, когда ничего другого уже не остается. Тем более, что необходимость вызова метода дальнего предка обычно свидетельствует о недостаточно продуманной архитектуре программы.
← →
[ВладОшин] © (2013-06-16 12:30) [9]
> Rouse_ © (16.06.13 12:08) [7]
понятно, так и подумал
Юрий Зотов © (16.06.13 12:23) [8]
> Подобные приемы следует применять КРАЙНЕ осторожно и лишь
> в исключительных случаях
Понятно. Буду всегда в исключительных :)
Словом, если понимаешь для чего и помнишь, что потоконебезопасно
← →
Юрий Зотов © (2013-06-16 12:34) [10]
> [ВладОшин] © (16.06.13 12:30) [9]
> Словом, если понимаешь для чего и помнишь, что потоконебезопасно
При коллективной разработке на это нельзя рассчитывать. Завтра ты уволился и на твое место пришел новый человек - который, естественно, и не подозревает о том, что в коде есть такие штучки.
← →
Inovet © (2013-06-16 12:48) [11]> [10] Юрий Зотов © (16.06.13 12:34)
> что в коде есть такие штучки
Потом историки расшифруют записку в коде: "Диверсия проведена по плану ЮЗ."
← →
Юрий Зотов © (2013-06-16 12:59) [12]
> Inovet © (16.06.13 12:48) [11]
То ли где-то читал, то ли кто-то рассказывал - не знаю, верить или нет. Из одной конторы увольнялся разработчик (сишник). Увольнялся с конфликтом - то ли ему что-то там недоплатили, то ли характер у него сволочной был, то ли еще что-то. Ну так вот - после его ухода программа начала неимоверно глючить и никто не мог понять, в чем дело.
Пока в одном из множества хидеров не обнаружили что-то в этом духе:
#define true false /* Счастливой отладки! */
← →
Юрий Зотов © (2013-06-16 13:07) [13]Хех... сказывается-таки влияние джавы - начал ставить лишние точки с запятой.
:o)
← →
Inovet © (2013-06-16 13:08) [14]> [12] Юрий Зотов © (16.06.13 12:59)
Тоже читал такое.:) Это из серии как можно, но не нужно делать.
← →
int64 © (2013-06-16 15:34) [15]
> Словом, если понимаешь для чего и помнишь, что потоконебезопасно
Тут еще полиморфизм пропадает. Если Proc каскадно содержит вызовы виртуальных методов, то будут вызваны только базовые методы ТА. Т.е. мы не просто метод предка предка вызываем, мы весь класс на предка предка меняем.
Это тоже надо помнить.
← →
Dimka Maslov © (2013-06-16 19:36) [16]Что-то типа
asm
mov eax, Self
call TGrandpa.Proc
end;
не прокатит?
← →
Inovet © (2013-06-16 20:51) [17]> [16] Dimka Maslov © (16.06.13 19:36)
Так эта... таблица-то виртуальная.
← →
Dimka Maslov © (2013-06-16 21:02) [18]
>
> Так эта... таблица-то виртуальная.
Тогда vmt offset для заданного класса?
← →
Inovet © (2013-06-16 21:06) [19]> [18] Dimka Maslov © (16.06.13 21:02)
Ну вызовешь, а смысл? Чем по сути это будет отличаться от приведения типа?
← →
Dimka Maslov © (2013-06-16 22:10) [20]
> Ну вызовешь, а смысл? Чем по сути это будет отличаться от
> приведения типа?
Мы возьмём адрес из таблицы виртуальных методов дедушки. И это не будет так грубо, как с подменой Self.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2014.03.23;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.006 c