delphi - self 的范围是什么?

标签 delphi

我要求加深对 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/

相关文章:

delphi - 如何将重载类方法分配给匿名方法?

arrays - 如何从Delphi函数返回数组?

multithreading - Delphi [volatile]和InterlockedCompareExchange不可靠吗?

delphi - 监控 Delphi 应用程序中的内存使用情况

delphi - 免注册 COM/DLL?

delphi - 在 Windows 8 上的 Delphi XE 中使用 Indy 时 Gmail 失败,错误代码为 'Connection Closed Gracefully'

delphi - 将 ISO 3166-1 alpha-2 国家/地区代码转换为本地化的国家/地区名称

delphi - LOCALE_INVARIANT 的 GetLocaleFormatSettings 返回 Windows XP 德语下的用户设置

sql - 监视 Delphi 应用程序执行的 SQL 查询

delphi - TCustomListbox 项目的自定义绘图