了解Delphi变量声明/初始化

了解Delphi变量声明/初始化,delphi,variable-assignment,variable-initialization,Delphi,Variable Assignment,Variable Initialization,因为它属于德尔福 当一个变量声明为某一类型时,它是否初始化为该类型的对象?或者必须为变量分配一个返回该类型对象的表达式 我有很强的Java背景。我想问的是。。。 在Java中,假设您声明了一个名为Orange的用户定义类型的实例变量。看起来是这样的: private Orange _fruit; _fruit = new Orange(); var Form : TForm; procedure TForm1.ShowForm2Click(Sender: TObject); begin

因为它属于德尔福

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

我有很强的Java背景。我想问的是。。。 在Java中,假设您声明了一个名为Orange的用户定义类型的实例变量。看起来是这样的:

private Orange _fruit;
_fruit = new Orange();
var
  Form : TForm;
procedure TForm1.ShowForm2Click(Sender: TObject);
begin
  with TSecondForm.Create(nil) do try
     ShowModal;
  finally
     Free;
  end;
end;
variable := ClassType.Create(arguments);
变量_fruit在实际分配Orange类的一个实例之前仍然保持对null的引用,如下所示:

private Orange _fruit;
_fruit = new Orange();
var
  Form : TForm;
procedure TForm1.ShowForm2Click(Sender: TObject);
begin
  with TSecondForm.Create(nil) do try
     ShowModal;
  finally
     Free;
  end;
end;
variable := ClassType.Create(arguments);
在Delphi中,如果我声明一个TForm类型的变量,如下所示:

private Orange _fruit;
_fruit = new Orange();
var
  Form : TForm;
procedure TForm1.ShowForm2Click(Sender: TObject);
begin
  with TSecondForm.Create(nil) do try
     ShowModal;
  finally
     Free;
  end;
end;
variable := ClassType.Create(arguments);
表单是否初始化为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。”我想这是因为我没有以某种方式初始化unit Main中的变量SecondForm?但是,我试图在ShowForm2Click过程中放置“SecondForm.Create”,得到了相同的错误。我是否因为第二个表单未分配而出现此错误?它需要初始化吗?还是这样

注:
我刚到德尔福三天。请考虑一下。

是的,
第二个表单
nil
,直到您分配它为止

试着这样做:

private Orange _fruit;
_fruit = new Orange();
var
  Form : TForm;
procedure TForm1.ShowForm2Click(Sender: TObject);
begin
  with TSecondForm.Create(nil) do try
     ShowModal;
  finally
     Free;
  end;
end;
variable := ClassType.Create(arguments);

SecondForm.Create
语法错误。构造函数在Delphi中是特殊的。您可以将它们或多或少地看作类方法。调用它们的方式如下所示:

private Orange _fruit;
_fruit = new Orange();
var
  Form : TForm;
procedure TForm1.ShowForm2Click(Sender: TObject);
begin
  with TSecondForm.Create(nil) do try
     ShowModal;
  finally
     Free;
  end;
end;
variable := ClassType.Create(arguments);
虽然可以像实例方法(
variable.Create
)那样调用构造函数,但这只适用于一个特定的用例,不应在常规代码中执行。对对象而不是类型调用构造函数的原因是您已经在该对象的构造函数中。(即,如果对象上有多个构造函数,其中一个调用另一个构造函数,或者通过使用
继承的Create(参数);
调用父类上的构造函数来初始化祖先类的成员)


当对象不在另一个构造函数中时,调用该对象上的构造函数,如果不是错误的话,可能会引发编译器警告,但不幸的是不会。请注意,
unit Second
unit Main
都声明了一个全局变量

SecondForm : TSecondForm; 
对于主机,您的主机将隐藏在
unit Second
中声明的
SecondForm
变量(即使它在
uses
子句中列出)。对于Delphi VCL表单应用程序,如果
SecondForm
是一个自动创建表单,那么
unit Second
中声明的
SecondForm
将不会
nil
,实际上已经创建并分配了一个
TSecondForm
实例,但是
unitmain
无法访问它,因为它声明了一个同名的全局变量(与所有引用类型一样,在您使用它之前,它将是
nil

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

除非您另有指定,否则VCL表单将自动创建表单。检查菜单:

 Project > Options > Forms

查看或更改哪些表单将自动将实例分配给IDE生成的全局对象。

这很有意义!非常感谢你!但我是否可以问一个问题来确保我理解?(我也是RAD环境的新手。)所以当我自动创建一个新的VCL表单时……它不需要实例化?但任何非自动创建的记录、类或表单等都必须实例化?@diosteama如果您查看项目代码(右键单击项目管理器中的可执行文件并查看源代码),您将看到Delphi生成了一些代码来实例化自动创建的表单。@diosteama-是的,基本上是这样。当您向项目中添加新表单时,IDE总是为表单添加一个全局实例变量,并将其放入自动创建列表中。这意味着它还创建代码来实例化该全局(正如Blorgbeard所指出的)。如果不希望实例化默认全局,只需从“自动创建”列表中删除该表单即可。@diosteama-此外,为了完整,您不必实例化记录(仅类);记录在声明时分配它们所需的所有空间。如果它们是引用类型的记录,那么它们的成员需要创建实例,否则记录只是原语或指针的包,不需要任何创建。你们太棒了。非常感谢你的帮助!非常感谢你!这是有道理的,而且帮助很大+1尽管我不得不说,这是我唯一可以容忍将
一起使用的场景。是的,这是我唯一可以将
一起使用的场景。