4

As it pertains to Delphi...

When a variable is declare of a certain type, is it initialized to an OBJECT of that type? Or must the variable be assigned an expression which returns an object of that type?

I'm coming from a strong Java background. What I mean to ask is this... In Java, say you declare an instance variable of a user defined type named Orange. Which would look like this:

private Orange _fruit;

The variable _fruit still holds a reference to null until actually assigned an instance of the Orange class, like this:

_fruit = new Orange();

In Delphi if I declare a variable of type TForm, like this:

var
  Form : TForm;

Is Form initlized to a TForm object? Or is it still nil?

I'm asking because I'm getting an error when trying to compile a small bit of code which is showen below:

Here is the Main unit:

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.

and here is the Second unit:

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.

The error I'm getting when I try to compile is exactly: "Access violation at address 005B17F9 in module 'Multiple.exe'. Read of address 00000000." I was thinking that it's because I don't somehow initialize the variable SecondForm in unit Main? However, I tried to place 'SecondForm.Create' in the ShowForm2Click procedure and I get the same error. Am I get this error because SecondForm is unassigned? Does it need to be initialized? Or is it?

Note: I'm three days new to Delphi. Please be considerate of that.

4

3 回答 3

5

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

variable := ClassType.Create(arguments);

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

您所做的,当不在该对象的另一个构造函数中时调用对象上的构造函数,如果不是错误,可能应该引发编译器警告,但不幸的是它没有。

于 2013-05-16T23:42:17.293 回答
3

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

SecondForm : TSecondForm; 

在主单元的情况下,您的主单元将隐藏SecondForm声明的变量unit Second(即使它在uses子句中列出)。在 Delphi VCL Forms 应用程序的情况下,如果它SecondForm是一个自动创建的表单,那么SecondForm声明的 inunit Second将不会nil并且实际上已经有一个TSecondFormcreated 并分配给它的实例,但这将是不可访问的,unit Main因为它声明了一个同名的全局变量(与所有引用类型一样,在nil您使用它之前将一直存在)。

简而言之,最好不要声明全局SecondForm : TSecondFormin unit Main- 将其称为其他名称,或者使用 in 中声明的全局unit Second。如果SecondForm是自动创建表单(默认行为),那么如果您只是没有重新声明SecondForm,上面的代码就可以工作unit Main- 如果不是,您仍然需要实例化SecondForm.

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

 Project > Options > Forms

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

于 2013-05-17T00:17:56.500 回答
3

是的,SecondForm直到nil你分配它。

尝试这样的事情:

procedure TForm1.ShowForm2Click(Sender: TObject);
begin
  with TSecondForm.Create(nil) do try
     ShowModal;
  finally
     Free;
  end;
end;
于 2013-05-16T23:10:22.527 回答