-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; 

您刚刚创建了两个对象 - 并为它们分配了堆内存。但是你没有释放他们。那是剩下的垃圾,它会不断增长,直到程序耗尽所有 Windows 内存并被杀死。

如果您想在没有任何准确性的情况下使用内存并且不“浪费”思考和学习时间 - 您最好使用一些在虚拟机中运行的托管语言,如 PHP、Python、Java 和其他基于 JVM、C# 和其他 .基于网络。

要编写好的 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 回答