我要求提升我对自我的理解。
请考虑以下事项:
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事件(MakeThePointer
)中调用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;
答案 0 :(得分:4)
Self的范围是什么?
在方法Self
中,最好将其视为局部变量。因此,它的地址@Self
在方法返回之前是有效的。
这解释了您的代码失败的原因。您的代码在方法返回后取消引用指针,此时指针无效。
我可以假设Self变量将始终位于同一地址吗?
不,你可能没有。
我认为你的问题从这里开始:
type
PTestObject = ^TTestObject;
由于TTestObject
是一个类,因此TTestObject
类型的变量(例如Self
)是一个参考。引用是指针的奇特名称。在这种情况下,Self
的{{1}}内部方法是指向实例的指针。
因此请使用TTestObject
代替TTestObject
,并解决您的问题。