delphi 为什么这段代码没有产生任何错误(访问冲突)并且正常工作?(MyHelloVar.Close的工作方式与Self.Close类似)

watbbzwu  于 2022-11-04  发布在  其他
关注(0)|答案(1)|浏览(121)

为什么这个命令会像“Self.Close”那样工作?
首先,我认为是这样的:
MyHelloVar. {空格...}关闭;
或为:
命令1:MyHelloVar. //但这不会编译它,还是?
命令2:{自身}关闭;
“MyHelloVar”本身的行为就好像她是主窗体的变量(示例)一样。
我所理解的是真的吗?
单位Unit 1;

interface

uses
  Winapi.Windows,
  Winapi.Messages,
  System.SysUtils,
  System.Variants,
  System.Classes,
  Vcl.Graphics,
  Vcl.Controls,
  Vcl.Forms,
  Vcl.Dialogs,
  Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
(* Summary:
  - RAD Studio 11.1 Alexandria
  - VCL Project 32bits (common case)
  - 1 form = my main form created automatically by IDE
  - 1 form = my second form not created automatically
  - 1 button to test!

* )

procedure TForm1.Button1Click(Sender: TObject);
var
  MyHelloVar: TForm;
begin
  // That's crazy behaviour!
  //
  MyHelloVar.Close; // this is close my "App" like "Self.Close" do it!
  //
end;

end.
bn31dyow

bn31dyow1#

使用 Delphi 7
内存中最后使用的是变量Form1,在事件处理器方法中,您只需对最后使用的内存使用相同的数据类型(即TForm)--这是它工作的唯一原因:存储器中相同位置的相同数据结构。
它还可以添加更多的表单并使用相同的代码--MyHelloVar变量将指向Form2Form3等(通过使用 Run〉Evaluate/Modify 计算变量的属性.Name,可以很容易地调试这些变量)。它看起来像self那样工作。

然而,只要您在该方法中使用更多变量,幻想世界就会分崩离析,例如:

var
  one, two,
  MyHelloVar: TForm;
begin
  self.Caption:= one.Caption+ two.Caption;
  MyHelloVar.Close();
end;

如果你现在计算onetwo(最后是MyHelloVar),你会看到很多不同的内容,执行它很可能会使你的程序崩溃。我也不知道为什么你忽略了编译器的警告,这些警告清楚地告诉你:
[警告] Unit1.pas(35)变量'one'可能尚未初始化
[警告] Unit1.pas(35)变量'two'可能尚未初始化
[警告] Unit1.pas(36)变量“MyHelloVar”可能尚未初始化
这不是魔术,只是巧合。这你不能相信。我能够重现这使用 Delphi 7,编译一个32位可执行在Win7 x64下。

使用FPC/Lazarus

Lazarus 2.2.0使用FPC 3.2.2会显示相同的编译警告:
警告:请注意:局部变量“MyHelloVar”似乎未初始化
......并且计算该变量时,已经显示它指向了一个非常不同的内存--结果程序在该点崩溃。这次它也是一个64位可执行文件。所以你的魔术甚至在该编译器或平台上都不起作用。

相关问题