我要求提高我对自我的理解.
请考虑以下事项:
type
PTestObject = ^TTestObject;
TTestObject = class(TObject)
private
FCaption : String;
public
procedure MakeThePointer;
property Caption : String read FCaption write FCaption;
end;
TForm4 = class(TForm)
ButtonFirst: TButton;
ButtonSecond: TButton;
ButtonThird: TButton;
procedure ButtonFirstClick(Sender: TObject);
procedure ButtonSecondClick(Sender: TObject);
procedure ButtonThirdClick(Sender: TObject);
private
public
end;
var
Form4: TForm4;
PointerOfTest : PTestObject;
TestObj : TTestObject;
implementation
{$R *.dfm}
procedure TTestObject.MakeThePointer;
begin
PointerOfTest := @Self;
end;
procedure TForm4.ButtonFirstClick(Sender: TObject);
begin
TestObj := TTestObject.Create;
TestObj.Caption := 'Hello';
TestObj.MakeThePointer;
end;
procedure TForm4.ButtonSecondClick(Sender: TObject);
begin
TestObj.MakeThePointer;
ShowMessage(PointerOfTest^.Caption);
end;
procedure TForm4.ButtonThirdClick(Sender: TObject);
begin
// TestObj.MakeThePointer; - Because I do not do this I get Access Violation
ShowMessage(PointerOfTest^.Caption);
end;
Run Code Online (Sandbox Code Playgroud)
我们的想法是创建一个指针TestObj's Self,然后再次访问它.如果我MakeThePointer在同一个Click事件(ButtonSecondClick)中调用我访问该指针它可以正常工作.如果我MakeThePointer在访问指针(ButtonThirdClick)之前没有调用那么它似乎TestObj's Self不存在以前创建的指针有效并且我得到访问冲突.
如果我错了,请纠正我,但我认为Self是每个对象方法的局部变量.因此,它将仅分别针对每种方法的范围?
现在考虑一下......如果是这种情况,那么为什么如果单击ButtonFirst,则下面的工作会起作用,然后是ButtonSecond?似乎Self变量已落在同一地址上,因此允许以下工作.我可以假设Self变量将始终位于同一地址或将更改吗?
type
TFormOther = class(TForm)
ButtonFirst: TButton;
ButtonSecond: TButton;
procedure ButtonFirstClick(Sender: TObject);
procedure ButtonSecondClick(Sender: TObject);
private
public
procedure MakeThePointer;
procedure SetTheCaption;
end;
var
FormOther: TFormOther;
PointerOfForm : ^TForm;
implementation
{$R *.dfm}
procedure TFormOther.MakeThePointer;
begin
PointerOfForm := @Self;
end;
procedure TFormOther.SetTheCaption;
begin
PointerOfForm^.Caption := 'Hello';
end;
procedure TFormOther.ButtonFirstClick(Sender: TObject);
begin
MakeThePointer;
end;
procedure TFormOther.ButtonSecondClick(Sender: TObject);
begin
SetTheCaption;
end;
Run Code Online (Sandbox Code Playgroud)
自我的范围是什么?
在方法中Self最好将其视为局部变量。因此,它的地址@Self一直有效,直到该方法返回。
这解释了为什么您的代码失败。您的代码在方法返回后取消引用该指针,此时该指针无效。
我可以假设 Self 变量始终位于同一地址吗?
不行,你不可以。
我认为你的问题从这里开始:
type
PTestObject = ^TTestObject;
Run Code Online (Sandbox Code Playgroud)
因为TTestObject是一个类,类型 的变量TTestObject,比如 your Self,是一个引用。引用是指针的一个奇特名称。在这种情况下,您的Self, 内部方法TTestObject是指向实例的指针。
所以使用TTestObject代替^TTestObject,你的问题就解决了。