delphi 如果类示例不是在调用过程中定义的变量,为什么在类中创建窗体时会发生访问冲突

m2xkgtsf  于 2023-01-20  发布在  其他
关注(0)|答案(1)|浏览(112)

我正在尝试使用类来显示进度指示器。
如果我在调用过程中将ProgressIndicator声明为变量,那么一切正常,并且ANewForm如我所期望的那样显示。
然而,下面的代码产生了访问冲突。有人能帮助我理解为什么吗?

unit Main;

interface

*uses
  Winapi.Windows, Vcl.Forms,
  System.Classes, Vcl.Controls, Vcl.StdCtrls,
  Progress;
type
  TProgressIndicator = class
  private
  public
    ANewForm : TForm;
    constructor Create;
  end;
type
  TfmMain = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    ProgressIndicator : TProgressIndicator;
  end;
var
  fmMain: TfmMain;
implementation
{$R *.dfm}
constructor TProgressIndicator.Create;
  begin
     ANewForm := TForm.Create(Application);
     ANewForm.Show;
  end;
procedure TfmMain.Button1Click(Sender: TObject);
  begin
    ProgressIndicator.Create;
  end;
end.
l7mqbcuq

l7mqbcuq1#

ProgressIndicator.CreateTProgressIndicator.Create之间有一个区别。通常,你想使用第二种形式,它说,“创建类TProgressIndicator的一个新示例“。第一种形式说,“取TProgressIndicator的一个示例,它存储在变量ProgressIndicator中,并调用它的Create方法”。问题是,它创建那个示例,在您的例子中,ProgressIndicatornil,因为所有类成员在构造时都被初始化为类似零的值,这本身不是问题--它仍然链接到类数据,因此实际上可以调用Create方法。该方法尝试创建表单,并成功创建。然后尝试将其存储到ANewForm字段,因为ANewForm的存储器内地址是Self + offset;对于你的代码,偏移量可能是0,Self是nil,这给出了(nil + 0) = 0的最终地址,并且内存位置0位于禁止所有访问的内存页中,这就是为什么你会得到访问冲突。
你想要的是:

procedure TfmMain.Button1Click(Sender: TObject);
  begin
    ProgressIndicator := TProgressIndicator.Create;
  end;

这将首先创建一个新示例,然后使用该示例。

相关问题