Форум: "Потрепаться";
Текущий архив: 2003.01.09;
Скачать: [xml.tar.bz2];
ВнизНарочно не придумаешь... Найти похожие ветки
← →
han_malign (2002-12-18 16:59) [0]... - но самое интересное, что учитывая особенности компилятора Delphi, код придуманный одним юным "гением" не валится, хотя по всем параметрам должен:
(Было в форуме "Основная", ветка потерялась, что-то вроде - как прилепить к классу - []).
Привожу немного в измененном виде, но смысл не теряется:
- и вот после этого кедр спрашивает, заметьте, не почему это падает, а почему 10 раз показывается значение 10.
..................
type
TMyClas = class
iMyInt: integer;
procedure SetItem(Index: integer; Value: TMyClass);
function GetItem(Index: integer): TMyClass;
property Items[Index: integer]: TMyClass read GetItem write SetItem; default;
end;
implementation
procedure TMyClass.SetItem(Index: integer; Value: TMyClass);
begin
//пусто!!!
end;
function TMyClass.GetItem(Index: integer): TMyClass;
begin
//пусто!!!
end;
procedure TForm1.Form1Button1Click(Sender: TObject);
var a: TMyObject;
i: integer;
begin //здесь привожу максимально точно, то что делал этот кедр
a:=TMyObject.Create;
for i:=1 to 10 do begin
a[i].iMyInt:=i;
end;
for i:=1 to 10 do ShowMessage(IntToStr(a[i].iMyInt));
end;
А теперь викторина - тот кто скажет почему это не упало, и откуда взялось 10 раз 10 - тот может считать себя, если не Мастером, то на пол-пути к этому.
ВНИМАНИЕ: Тем кто разобрался быстрее чем за пять минут, можно только флеймить, а молодежь пускай трудится(иначе не интересно).
З.Ы. 100% - что генерируемый код, абсолютно корректен и стабилен(помимо утечки памяти(если придираться),ни каких Run-time ошибок), правда абсолютно бесполезен (хотя можно использовать как альтернативный метод передачи параметров в функию).
← →
han_malign (2002-12-18 17:25) [1]Намек - EAX
← →
Anatoly Podgoretsky (2002-12-18 17:29) [2]Тут нет никаких оснований что бы падало, и какая разница, какое знаечение имеет не инициализированный Result
← →
Ru (2002-12-18 17:31) [3]Ж:)))
← →
han_malign (2002-12-18 17:41) [4]Ну почему же неинициализированный, вполне инициализированный, неявно правда, на счет разницы - вы надеюсь заметили разадрессацию - a[] . .
← →
DiamondShark (2002-12-18 17:47) [5]Вот так оно правилнЕе будет:
type
TMyClass = class
iMyInt: integer;
procedure SetItem(Index: integer; Value: TMyClass);
function GetItem(Index: integer): TMyClass;
property Items[Index: integer]: TMyClass read GetItem write SetItem; default;
end;
procedure TMyClass.SetItem(Index: integer; Value: TMyClass);
begin
//пусто!!!
end;
function TMyClass.GetItem(Index: integer): TMyClass;
begin
//пусто!!!
end;
procedure TForm1.Button1Click(Sender: TObject);
var a: TMyClass;
i: integer;
begin //здесь привожу максимально точно, то что делал этот кедр
a:=TMyClass.Create;
for i:=1 to 10 do begin
a[i].iMyInt:=i;
end;
for i:=1 to 10 do ShowMessage(IntToStr(a[i].iMyInt));
end;
← →
DiamondShark (2002-12-18 17:53) [6]
> Anatoly Podgoretsky © (18.12.02 17:29)
Очень даже есть основания падать.
> han_malign © (18.12.02 17:25)
> Намек - EAX
Угу. Намек понял.
Еще намек:
ShowMessage(IntToStr(a.iMyInt));
Можно воткнуть в любое место.
← →
Ketmar (2002-12-18 17:54) [7]у-у-у... что люди пишут-то. а я думал, что я профи... нифига. я - последний чайник %-) этот код надо куда-нибудь сохранить, чтобы пугать сотрудников... %-)
Satanas Nobiscum! 18-Dec-XXXVII A.S.
← →
han_malign (2002-12-18 18:00) [8]Да я сам - полдня в восторге пребывал :))
З.Ы. Нужно заметить, что одним из очередных вопросов, в оригинальной ветке, был - "А как мне теперь создать экземпляр этого класса"
← →
Sha (2002-12-20 10:52) [9]По-настоящему круто. И никогда не упадет.
Потому что то, на что намекал han_malign © (18.12.02 17:25), равно Self и на входе и на выходе. Во как :)
Будет работать даже, если заменить a[i] на a[MaxInt] или даже просто на a (это намек :)
Ошибку легко "исправить" - переставим ShowMessage(IntToStr(a[i].iMyInt));
внуть первого цикла сразу за a[i].iMyInt:=i; - и все дела.
Где бы это применить...
← →
Дмитрий К.К. (2002-12-20 11:06) [10]А почему в одном месте TMyClass, в другом TMyObject? Такой код точно не откомплится.
← →
Sha (2002-12-20 12:06) [11]2 Дмитрий К.К. © (20.12.02 11:06)
Исправь или попробуй вариант от DiamondShark © (18.12.02 17:47).
← →
Sha (2002-12-20 17:48) [12]2 han_malign © (18.12.02 16:59)
Мне не удалось использовать сие творение как альтернативный метод передачи параметров в функцию, если только перед выходом из нее явно не присваивать Result:=Self;
Когда тело функции не пусто, компилятор под временный Result выделяет не обязательно eax.
← →
han_malign (2002-12-20 17:54) [13]На самом делее передается Result через EAX, но практически лыбые операции идут с использованием этого регистра и начальное значение просто переписывается каким-то промежуточным, так что нужно ручками делать push EAX в начале и pop EAX в конце функции, на самом деле насчет альтернативного метода - это была шутка.
← →
Sha (2002-12-20 18:38) [14]2 han_malign © (18.12.02 16:59)
На самом делее Result возвращается через EAX, а во время работы функции он может временно лежать на стеке или в любом регистре.
Ручками push/pop не поможет, prolog/epilog их скушает.
Насчет шутки - если делать в конце Result:=Self, то все работает как часы.
← →
Sha (2002-12-21 13:58) [15]Кажется, я придумал, как это безобразие можно использовать.
Если, конечно, вы не боитесь вывихнуть мозги сослуживцам (и себе по прошествии некоторого времени), то подобные конструкции могут быть использованы для смены контекста объекта.
Ниже приводится фрагмент программы, вычисляющей объем прямоугольной коробки в контексте высоты коробки.
type
TMyClass = class
private
FContext: integer;
function SetContext(Value: integer): TMyClass;
procedure CopyContextDef(Value: integer; CopyFrom: TMyClass);
function GetVolume: integer;
public
dx: integer;
dy: integer;
property Context[Value: integer]: TMyClass read SetContext write CopyContextDef; default;
property Vol: integer read GetVolume;
end;
function TMyClass.SetContext(Value: integer): TMyClass;
begin
FContext:=Value; Result:=Self;
end;
procedure TMyClass.CopyContextDef(Value: integer; CopyFrom: TMyClass);
begin;
if CopyFrom=nil then FContext:=Value else FContext:=CopyFrom.FContext;
end;
function TMyClass.GetVolume: integer;
begin;
Result:=dx * dy * FContext;
end;
procedure TForm1.Button6Click(Sender: TObject);
var
a, b: TMyClass;
begin;
a:=TMyClass.Create;
b:=TMyClass.Create;
// Установка контекста(высоты) и длины и ширины
a[2].dx:=3; a.dy:=4; ShowMessage(IntToStr(a.Vol));
// Смена контекста(высоты)
a[5]; ShowMessage(IntToStr(a.Vol));
// Копирование контекста(высоты) и установка длины и ширины
b[0]:=a; b.dx:=6; b.dy:=7; ShowMessage(IntToStr(b.Vol));
b.Free;
a.Free;
end;
← →
Fantasist (2002-12-22 07:30) [16]
> и откуда взялось 10 раз 10 - тот может считать себя, если
> не Мастером, то на пол-пути к этому.
Нуу... Тоже мне, критерий мастерства. :) Даже мне, человеку незнающего асма, не составило труда за эти 5 минут, в дизассемблированном коде, проследить эту махинацию. Да и до Мастера мне еще расти и расти. Эта штучка, конечно, забавна, но понять ее - это не Мастерство.
Страницы: 1 вся ветка
Форум: "Потрепаться";
Текущий архив: 2003.01.09;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.007 c