4

Delphi に関しては...

変数が特定の型を宣言するとき、その型の OBJECT に初期化されますか? それとも、その型のオブジェクトを返す式を変数に割り当てる必要がありますか?

私は強力な Java のバックグラウンドを持っています。私が聞きたいのはこれです... Javaで、Orangeという名前のユーザー定義型のインスタンス変数を宣言するとします。これは次のようになります。

private Orange _fruit;

次のように、実際に Orange クラスのインスタンスが割り当てられるまで、変数 _fruit は null への参照を保持します。

_fruit = new Orange();

Delphi で TForm 型の変数を宣言すると、次のようになります。

var
  Form : TForm;

Form は 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.

ここに2番目のユニットがあります:

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 が割り当てられていないため、このエラーが発生するのでしょうか? 初期化する必要はありますか?またはそれは?

注: 私は Delphi を使い始めて 3 日目です。その点、ご配慮ください。

4

3 に答える 3

5

SecondForm.Create間違った構文です。コンストラクタは、Delphi では特別です。それらは多かれ少なかれクラス メソッドのように考えることができます。それらを呼び出す方法は次のとおりです。

variable := ClassType.Create(arguments);

インスタンス メソッド ( ) のようなコンストラクタを呼び出すことは可能ですが、variable.Createこれは 1 つの特定のユース ケースのためであり、一般的なコードでは実行しないでください。型ではなくオブジェクトでコンストラクターを呼び出す理由は、そのオブジェクトのコンストラクター内に既にいる場合です。 (つまり、オブジェクトに複数のコンストラクターがあり、そのうちの 1 つが別のコンストラクターを呼び出す場合、または で親クラスのコンストラクターを呼び出して祖先クラスのメンバーを初期化する場合inherited Create(arguments);)

オブジェクトの別のコンストラクター内にないときにオブジェクトのコンストラクターを呼び出すと、エラーではないにしても、おそらくコンパイラーの警告が発生するはずですが、残念ながらそうではありません。

于 2013-05-16T23:42:17.293 に答える
3

はい、あなたSecondFormnilそれを割り当てるまでです。

次のようなことを試してください:

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

unit Secondまた、unit Main両方がグローバル変数を宣言していることにも注意してください

SecondForm : TSecondForm; 

メインユニットの場合、メインユニットはSecondForm宣言された変数を隠します(節unit Secondにリストされていますが)。usesDelphi VCL フォーム アプリケーションの場合、SecondFormが自動作成フォームの場合、SecondForm宣言されたunit Secondは存在せずnil、実際にはすでに のインスタンスがTSecondForm作成されて割り当てられていますが、これは によってアクセスできませんunit Main。同じ名前のグローバル (これは、すべての参照型と同様に、nil何かを行うまで続きます)。

要するに、グローバルSecondForm : TSecondForminを宣言しないことがおそらく最善です。unit Mainそれを何か別のものと呼ぶか、 in で宣言されたグローバルを使用しunit Secondます。がSecondForm自動作成フォーム (デフォルトの動作) の場合、 in を再宣言SecondFormしなければ上記のコードは機能します。unit Mainそうでない場合は、インスタンス化する必要がありますSecondForm

VCL フォームは、特に指定しない限り、自動的に自動作成されるフォームです。チェックメニュー:

 Project > Options > Forms

IDE で生成されたグローバルにインスタンスが自動的に割り当てられるフォームを表示または変更します。

于 2013-05-17T00:17:56.500 に答える