実際には、「Self」は、ヒープ内のオブジェクトを指すアドレスを格納するスタック上の場所への単なる名前参照です。この変数に読み取り専用を強制することは可能ですが、設計者はそうしないことに決めたようです。決定は恣意的だと思います。
これが便利な場合はわかりません。スタック内の値を変更するだけです。また、この値を変更すると、インスタンスのメンバーを参照するコードの動作がコンパイラのバージョン間で一貫しているという保証がないため、危険な場合があります。
更新:PatrickvL
コメントへの返信
'変数'"Self"はスタックにありません(私の知る限り、スタックにはありません)。代わりに、その値は、オブジェクトメソッドが呼び出される直前にレジスタ(正確にはEAX)に格納されます。– </ p>
いいえ、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;