Self
Delphiでオブジェクト参照がどのように機能するのか、そしてどのように機能するのかを誤解していると思います。
クラスのインスタンスを含む変数は、すでにそのオブジェクトインスタンスへのポインタです。Delphiコンパイラでは、便宜上、間接参照演算子(^
)を省略できます。
var
MyObject: TMyObject;
begin
MyObject := TMyObject.Create; // MyObject is now a pointer to an instance of TMyObject
...
Delphiでは、オブジェクトインスタンスのメンバーまたはプロパティにアクセスするときに、逆参照演算子を使用しないという省略形も使用できます。繰り返しますが、次のコードは実際には同等です。
MyObj.SomeProperty := SomeValue;
MyObj^.SomeProperty := SomeValue;
Delphiのドキュメントから:
クラス型の変数は、実際にはオブジェクトを参照するポインターです。したがって、複数の変数が同じオブジェクトを参照できます。他のポインターと同様に、クラス型変数は値nilを保持できます。ただし、それが指すオブジェクトにアクセスするために、クラス型変数を明示的に逆参照する必要はありません。たとえば、SomeObject.Size:= 100は、SomeObjectによって参照されるオブジェクトのSizeプロパティに値100を割り当てます。これをSomeObject^.Size:=100とは書きません。
Self
オブジェクトの現在のインスタンスを指す、自動的に宣言されたプロパティです。つまり、オブジェクトの現在のインスタンスを参照するためにそのクラスを実装するコード内で自動的に利用可能になります。これにより、同じオブジェクトの複数のインスタンスを持つことができます。
type
TMyObject=class(TObject)
private
FMyInteger: Integer;
function GetMyInteger: Integer;
procedure SetMyInteger(Value: Integer);
published
property MyInteger: Integer read GetMyInteger write SetMyInteger;
end;
...
function TMyObject.GetMyInteger: Integer;
begin
Result := Self.FMyInteger;
// Self is implied, so the above line can more simply be written as
// Result := FMyInteger;
end;
procedure TMyObject.SetMyInteger(Value: Integer);
begin
if (Value <> Self.FMyInteger) then // Self is again implied here
Self.FMyInteger := Value;
end;
var
MyObjOne, MyObjTwo: TMyObject;
i, j: Integer;
begin
MyObjOne := TMyObject;
// Here, the code inside TMyObject.SetInteger that
// uses `Self` would refer to `MyObjOne`
MyObjOne.MyInteger := 1;
MyObjTwo := TMyObject;
// Here, the code in TMyObject.SetInteger would be
// using the memory in `MyObjTwo` when using `Self`
MyObjTwo.MyInteger := 2;
end;
これは、クラスを実装するコードでSelf
のみ有効であることに注意してください。これは、上記で使用可能で有効であり(私の例では実装されている唯一のコード)、常に現在のインスタンスを参照します。TMyObject.GetMyInteger
TMyObject.SetMyInteger
Self
そのオブジェクトインスタンスを参照する変数は Self
そのオブジェクトインスタンスのメソッド内にあるため、のアドレスを追跡する必要はありません。オブジェクトのそのインスタンス内でのみ有効であり、常にそのオブジェクトインスタンスを参照します。したがって、コード例でPSelf
は、スペースが無駄になっています-myobject
すでにそれ自体へのポインターが含まれており、そのポインターは次のメソッドで自動的に使用可能になりますmyobject
。
type
myobject = class; // Now automatically contains a `Self` pointer
// available in methods of the class once an
// instance is created
var
myobj: myobject;
begin
myobj := myobject.Create; // myobj.Self now is valid in methods of
// `myobject`