【问题标题】:Error When Editing Member Variable in Class在类中编辑成员变量时出错
【发布时间】:2014-02-16 18:45:28
【问题描述】:

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

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;

并像这样调用构造函数来初始化'Count':

Stack.Create;

【问题讨论】:

  • 哪一行崩溃,构造函数中的还是Add中的?
  • 很多问题。可能伤害您的是您没有正确创建对象。您没有显示该代码。请做。使用整数来计数,而不是字节。不要使用静态数组。使用动态数组或TList<T>。从0开始索引数组。不要取局部变量的地址。
  • 是的,Stack.create 不起作用但stack=Tstack.create 解决了一些问题(为什么?!)!为什么我不应该使用静态数组?! “不要取局部变量的地址”是什么意思!谢谢你们:)
  • OT:有一个现成的TObjectStack 类(根据您显示的代码)您可以为您的任务实现。
  • @TLama 我认为Rec 是一个记录,一个值类型,因此不适合TObjectStack。此外,TObjectStack 是遗留的,因为我们有泛型。

标签: class delphi constructor delphi-xe4


【解决方案1】:

如 cmets 中所述,您正尝试像这样创建对象:

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

这是一个典型的错误,我们都犯过。您正在对未初始化的实例变量调用方法。

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

Stack := TStack.Create;

除此之外,我还有以下 cmets:

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

更详细地选择第 5 项,您的记录声明如下:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-03
    • 2019-10-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多