-2

これは、明確な答えが見つからない非常に単純な質問です。時間に追われているため、このドキュメントをすべて読む時間はありません。

しかし、ここにあります。

次のように、TForm クラスの上に新しいクラスを作成しました。

 Bucket = Class
   glass: Integer;
   steel: Integer;
 End;

次に、TForm1 に属するメソッドでいくつかのオブジェクトを作成します

procedure TForm1.getMarbles;
var
  objPlastic: Bucket;
  objAlu: Bucket;

begin
  // Initialize objects
  objPlastic := Bucket.Create;
  objAlu := Bucket.Create;

  // Get Values from edtBox
  val(Edit1.Text, objPlastic.steel, code);
  val(Edit2.Text, objAlu.steel, code);
  val(Edit3.Text, objPlastic.glass, code);
  val(Edit4.Text, objAlu.glass, code);
end; 

私の問題は、これらのオブジェクトを他のメソッドで使用する方法がわからないことです。それらを使用したい他の方法でこれまでに知っているすべての方法でそれらを定義しようとしましたが、機能させることができません。

これがメソッドと、現在設定されているものです(常に0を返します):

procedure TForm1.marbleDrop(kind: string);
var
  objPlastic: Bucket;
  I: Integer;
begin
  objPlastic := Bucket.Create;
  if kind= 'plastic' then // the function is receiving this parameter
  begin
    for I := 0 to objPlastic.glass do
    begin
      showmessage(inttostr(objPlastic.glass)); //returns 0
    end;
  end;

end;

この種の質問で申し訳ありませんが、より良い方法が見つかりませんでした。

ところで、これは私が使用しているコードの簡略化されたバージョンです。これは私が実際に使用しているものの翻訳であるため、タイプミスをなくすために最善を尽くしましたが、それは主にアイデアに関するものです. Delphi のコードにタイプミスはありません。

4

2 に答える 2

5

メソッド間でオブジェクトにアクセスするには、次のいずれかを行う必要があります。

  1. オブジェクトを Form クラスのメンバーとして宣言します。

    type
      TForm1 = class(TForm);
      ...
      private
        objPlastic: Bucket;
        objAlu: Bucket;
      ...
      end;
    
    procedure TForm1.getMarbles;
    begin
      // Initialize objects
      if objPlastic = nil then objPlastic := Bucket.Create;
      if objAlu = nil then objAlu := Bucket.Create;
    
      // Get Values from edtBox
      objPlastic.steel := StrToIntDef(Edit1.Text, 0);
      objAlu.steel := StrToIntDef(Edit2.Text, 0);
      objPlastic.glass := StrToIntDef(Edit3.Text, 0);
      objAlu.glass := StrToIntDef(Edit4.Text, 0);
    end;
    
    procedure TForm1.marbleDrop(kind: string);
    begin
      if (kind = 'plastic') and (objPlastic <> nil) then
      begin
        ShowMessage(IntToStr(objPlastic.glass));
      end;
    end;
    
  2. それらをメソッド自体のパラメーターとして渡します。

    procedure TForm1.getMarbles(objPlastic, objAlu: Bucket);
    begin
      // Get Values from edtBox
      if objPlastic <> nil then
      begin
        objPlastic.steel := StrToIntDef(Edit1.Text, 0);
        objPlastic.glass := StrToIntDef(Edit3.Text, 0);
      end;
      if objAlu <> nil then
      begin
        objAlu.steel := StrToIntDef(Edit2.Text, 0);
        objAlu.glass := StrToIntDef(Edit4.Text, 0);
      end;
    end;
    
    procedure TForm1.marbleDrop(objWhichKind: Bucket);
    begin
      if objWhichKind <> nil then
      begin
        ShowMessage(IntToStr(objWhichKind.glass));
      end;
    end;
    
    procedure TForm1.someMethod();
    var
      objPlastic: Bucket;
    begin
      objPlastic := Bucket.Create;
      getMarbles(objPlastic, nil);
      marbleDrop(objPlastic);
      objPlastic.Free;
    end;
    
于 2012-12-12T10:52:25.910 に答える
1

もちろん、ゼロを返します。別のオブジェクトです。他のパラメータ変数を渡すときと同じように渡す必要があります。あなたが作ったものは似ています

procedure TForm1.Drop1(kind: string);
begin
   marbleDrop(); // here kind = "staal"
end;

procedure TForm1.marbleDrop();
var
  kind: string;
begin
  if kind = 'plastic' then // it is not !!! why ???
  begin
....
  end;
end;

また、別の問題があります-メモリリーク

  val(Edit4.Text, objAlu.glass, code);
end; 

2つのオブジェクトを作成し、それらにヒープメモリを割り当てました。しかし、あなたはそれらを解放しませんでした。それは残されたゴミであり、プログラムがすべてのWindowsメモリを使い果たして殺されるまで、それは成長し、成長し、成長します。

正確さを欠き、思考や学習に時間を「無駄にする」ことなくメモリを使用したい場合は、PHP、Python、Java、その他のJVMベース、C#などの仮想マシンで実行されているマネージド言語を使用することをお勧めします。 NEtベース。

優れたDelphiコードを作成するには、CPUの機能とその理由を少なくともある程度理解している必要があります。


特にあなたのコードではあなたがより良いでしょう

  1. クラスの代わりにレコードを使用する
  2. 冗長なコピーを避けるために、const-またはパラメータとしてそれらを渡します。var-

そのように:

type TBucket = Record  glass, steel: Integer; End;
type TForm1 = class (TForm) 
     .....
 private
   var objPlastic, objAlu: TBucket;
    (* making variables more global: now they are form-local not function-local *)
......

procedure TForm1.getMarbles;
begin
   objPlastic.steel := StrToIntDef(Edit1.Text, 0);
   objAlu.steel := ...
   Self.objPlastic.glass ...  (* adding Self - just for clarity where those variable are taken from *)
   Self.objAlu.glass ....
end; 

procedure TForm1.marbleDrop(kind: string);
var
  I: Integer;
begin
  if kind = 'plastic' then // the function is receiving this parameter
  begin
    for I := 0 to Self.objPlastic.glass do
    begin
      showmessage(inttostr(objPlastic.glass)); 
        //getting via common parent context - TForm1 object, referenced as Self pseudo-variable
      marbleTell(objPlastic); // passing as parameter
    end;
  end;
end;

procedure TForm1.marbleTell(const arg: TBucket);
// do not forget to use const to pass variable by-reference not by-value
begin
   showmessage(inttostr(arg.glass)); // getting via argument
end;
于 2012-12-12T10:37:36.337 に答える