在类中编辑成员变量时出错

时间:2014-02-16 18:45:29

标签: class delphi constructor delphi-xe4

我正在尝试在我的程序中使用一个类。

TStack = Class
Public
  constructor Create; Overload;
  Procedure Add(Frm:TForm);
  Procedure Remove();
  Procedure Do_Close;

 Private
  List  : Array[1..Max_Forms] of Rec;
  Count : Byte;
End;

构造

constructor TStack.Create;
begin
  Self.Count := 0;
end;

Procedure TStack.Add(Frm:TForm);
begin
  Inc(Self.Count);
  List[Count].Form     := @Frm;
  List[Count].Width    := Frm.Width;
  List[Count].Height   := Frm.Height;
  List[Count].left     := Frm.Left;
  List[Count].Top      := Frm.Top;
end;

我无法更改Count变量的值!它导致运行时错误:访问冲突....写入地址000001E4

有什么问题?!

了解更多信息:

我正在尝试在这样的结构中存储指向每个表单的指针:

  Rec = Record
      Form      : ^TForm;
      Maximized : Boolean;
      Width,
      Height,
      left,
      Top       : Integer;
    End;

然后

Procedure TStack.Do_Close;
var
  i      : integer;
  MyForm : TForm;
begin
 i := .....some code here.......;
 MyForm := @List[i].Form;
 ShowMessage('I will close '+MyForm.Caption);
 MyForm.Close;
end;

AND调用这样的构造函数来初始化'Count':

Stack.Create;

1 个答案:

答案 0 :(得分:4)

如评论中所述,您试图创建这样的对象:

var
  Stack: TStack;
....
Stack.Create;

这是一个经典的错误,也是我们所做的一个错误。您正在调用未初始化的实例变量上的方法。

为了实例化一个类,你需要写一下:

Stack := TStack.Create;

最重要的是,我有以下评论:

  1. 对数组使用从零开始的索引。这是Delphi中除了不合时宜的字符串之外的所有惯例。甚至在新版本中也会发生变化。
  2. 除非您有充分理由这样做,否则不要将静态数组用于堆栈。你只会冒着空间不足的风险。或者分配比你需要的更多的内存。使用动态数组。
  3. 您可以使用TList<T>
  4. 而不是动态数组
  5. 即便如此,当有完美的TStack<T>时,人们会想知道为什么要自己创建堆栈类。
  6. 您将本地变量的地址存储在堆栈中。在TStack.Add中,您将@Frm添加到容器中。只要TStack.Add返回,@Frm就毫无意义。那是因为Frm是一个局部变量,它的生命在拥有它的函数返回时结束。我想你想要复制Frm
  7. 更详细地提取第5项,您的记录如下所示:

    Rec = Record
      Form      : ^TForm;
      Maximized : Boolean;
      Width,
      Height,
      left,
      Top       : Integer;
    End;
    

    使用^TForm是错误的。这是一个指向变量的指针,该变量包含指向对象的指针。这是间接的两个层次,一个太多。您必须将Form字段声明为TForm类型。我建议你修改Delphi对象引用变量的工作方式。 Delphi类就是所谓的引用类型。 TMyClass TMyClass class(...)类型的变量已经是指针。当您使用.运算符访问成员时,该语言会自动取消引用指针。