了解Delphi变量声明/初始化

时间:2013-05-16 23:06:18

标签: delphi variable-assignment variable-initialization

因为它与Delphi有关...

当变量声明某种类型时,它是否初始化为该类型的OBJECT?或者必须为变量分配一个表达式,该表达式返回该类型的对象?

我来自强大的Java背景。我的意思是这个...... 在Java中,假设您声明了一个名为Orange的用户定义类型的实例变量。看起来像这样:

private Orange _fruit;

变量_fruit仍然保持对null的引用,直到实际分配了一个Orange类的实例,如下所示:

_fruit = new Orange();

在Delphi中,如果我声明一个类型为TForm的变量,就像这样:

var
  Form : TForm;

表单是否已初始化为TForm对象?或者它仍然是零?

我问,因为我在尝试编译一小段代码时出现错误,如下所示:

这是主要单位:

unit Main;

interface

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

type
  TForm1 = class(TForm)
    ShowForm2: TButton;
    procedure ShowForm2Click(Sender: TObject);
  end;

var
  Form1: TForm1;
  SecondForm : TSecondForm;

implementation

{$R *.dfm}

procedure TForm1.ShowForm2Click(Sender: TObject);
begin
SecondForm.ShowModal;
end;
end.

这是第二单元:

unit Second;

interface

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

type
  TSecondForm = class(TForm)
    Label1: TLabel;
  end;

var
  SecondForm: TSecondForm;

implementation

{$R *.dfm}

end.

我尝试编译时遇到的错误正是:“模块'Multiple.exe'中地址005B17F9的访问冲突。读取地址00000000.”我以为这是因为我不以某种方式初始化单元Main中的变量SecondForm?但是,我试图在ShowForm2Click过程中放置​​'SecondForm.Create',我得到了同样的错误。我是否因为SecondForm未分配而收到此错误?是否需要初始化?或者是吗?

注意: 我对德尔福有三天的新见事。请考虑周到。

3 个答案:

答案 0 :(得分:5)

SecondForm.Create语法错误。构造函数在Delphi中很特殊。您可以将它们或多或少地视为类方法。你调用它们的方式是这样的:

variable := ClassType.Create(arguments);

虽然可以像实例方法(variable.Create)那样调用构造函数,但这是针对一个特定用例的,不应该在通用代码中完成。如果你已经在该对象的构造函数中,那么在对象而不是类型上调用构造函数的原因是(即,如果对象上有多个构造函数,其中一个构造函数)调用另一个,或通过使用inherited Create(arguments);调用父类的构造函数来初始化祖先类的成员

你做了什么,当不在另一个对象的构造函数内时调用对象上的构造函数,应该引发编译器警告,如果不是错误,但遗憾的是它没有。

答案 1 :(得分:3)

是的,SecondFormnil,直到您指定它为止。

尝试这样的事情:

procedure TForm1.ShowForm2Click(Sender: TObject);
begin
  with TSecondForm.Create(nil) do try
     ShowModal;
  finally
     Free;
  end;
end;

答案 2 :(得分:3)

还要注意unit Secondunit Main都声明了一个全局变量

SecondForm : TSecondForm; 

对于主单元,主单元将隐藏SecondForm中声明的unit Second变量(即使它在uses子句中列出)。对于Delphi VCL Forms应用程序,如果SecondForm是自动创建表单,则SecondForm中声明的unit Second将不是nil,实际上已经已创建并分配了TSecondForm的实例,但unit Main无法访问此实例,因为它声明了一个同名的全局(与所有引用类型一样,nil直到你用它做某事。)

简而言之,最好不要在SecondForm : TSecondForm中声明全局unit Main - 将其称为其他内容,或者使用unit Second中声明的全局。如果SecondForm是自动创建表单(默认行为),那么如果您只是在SecondForm中没有重新声明unit Main,则上述代码将起作用 - 如果不是,您仍然需要实例化SecondForm

除非另有说明,否则VCL表格会自动自动创建表格。检查菜单:

 Project > Options > Forms

查看或更改哪些表单将自动为其IDE生成的全局变量分配实例。