我要求加深对 self 的理解。
请考虑以下事项:
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;
这个想法是创建一个指向TestObj's Self
的指针,然后再次访问它。如果我在访问该指针的同一 Click 事件 (ButtonSecondClick
) 中调用 MakeThePointer
,则它可以正常工作。如果我在访问指针(ButtonThirdClick
)之前没有调用MakeThePointer
,那么似乎TestObj的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;
最佳答案
What is the scope of Self?
在方法中,Self
最好被视为局部变量。因此,其地址 @Self
在该方法返回之前一直有效。
这解释了您的代码失败的原因。您的代码在方法返回后取消引用该指针,此时该指针无效。
May I assume that the Self variable will always be on the same address?
不,你可能不会。
<小时/>我认为你的问题从这里开始:
type
PTestObject = ^TTestObject;
因为TTestObject
是一个类,TTestObject
类型的变量,比如你的Self
,是一个引用。引用是指针的一个奇特名称。在这种情况下,TTestObject
内部方法中的 Self
是指向实例的指针。
因此,使用 TTestObject
而不是 ^TTestObject
,您的问题就会迎刃而解。
关于delphi - self 的范围是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42085424/