На самом деле «Я» — это просто ссылка на имя места в стеке, в котором хранится адрес, указывающий на объект в куче. Принудительное использование только чтения для этой переменной возможно, по-видимому, дизайнер решил этого не делать. Я считаю решение произвольным.
Не вижу ни одного случая, когда это было бы полезно, просто изменило бы значение в стеке. Кроме того, изменение этого значения может быть опасным, поскольку нет гарантии, что поведение кода, ссылающегося на член экземпляра, будет одинаковым для всех версий компилятора.
Обновлено: в ответ на PatrickvL
комментарий
«Переменная» «Я» не находится в стеке (насколько мне известно, никогда не бывает); Вместо этого его значение помещается в регистр (точнее, EAX) непосредственно перед вызовом любого метода объекта. –
Нет, у Self есть реальный адрес в памяти. Попробуйте этот код, чтобы убедиться в этом.
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(IntToStr(Integer(@Self)));
end;
procedure TForm1.Button2Click(Sender: TObject);
var
newform: TForm;
p: ^Integer;
begin
Self.Caption := 'TheOriginal';
newform := TForm.Create(nil);
try
newform.Caption := 'TheNewOne';
// The following two lines is, technically, the same as
// Self := newform;
p := Pointer(@Self);
p^ := Integer(newform);
ShowMessage(Self.Caption); // This will show 'TheNewOne' instead of 'TheOriginal'
finally
Self.Free; // Relax, this will free TheNewOne rather than TheOriginal
end;
end;
person
Sake
schedule
02.05.2009