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

Вниз

Нарочно не придумаешь...   Найти похожие ветки 

 
han_malign   (2002-12-18 16:59) [0]

... - но самое интересное, что учитывая особенности компилятора Delphi, код придуманный одним юным "гением" не валится, хотя по всем параметрам должен:
(Было в форуме "Основная", ветка потерялась, что-то вроде - как прилепить к классу - []).
Привожу немного в измененном виде, но смысл не теряется:

..................
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.

А теперь викторина - тот кто скажет почему это не упало, и откуда взялось 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.006 c
1-24960
Kventin
2002-12-26 19:41
2003.01.09
Класс - контейнер


4-25128
kserg@ukr.net
2002-11-20 12:54
2003.01.09
Как узнать автора файла


1-24874
Separator
2002-12-28 06:37
2003.01.09
StringGrid и полоса проктрутки


7-25110
HardJ
2002-10-30 10:39
2003.01.09
CTRL+ALT+DELETE в NT-ях


3-24798
Чадаева Ирина
2002-12-16 17:12
2003.01.09
Отчеты в Word e





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