繁体   English   中英

如果 class 实例不是调用过程中定义的变量,为什么在 class 中创建表单时出现访问冲突

[英]Why do I get an access violation when I create a form within a class if the class instance is not a variable defined in the calling procedure

我正在尝试使用 class 来显示进度指示器。

如果我将 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.

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

你想要的是:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM