delphi - 对象在主程序中崩溃,但在移动到单元时不会崩溃

标签 delphi pascal freepascal

我编写了一个自定义 SDL GUI 工具包(来源位于 http://sourceforge.net/projects/lkgui/files/ ),但我遇到了继承对象的问题。

当对象位于主程序中时,不会调用构造函数,因此程序无法正确初始化对象,并且在执行某些命令后会崩溃(具体来说,TStartGameButton 继承自 GUI_Canvas 继承自 GUI_Element 以及任何未定义的内容) GUI_Element 中的程序因 EAccessViolation 而崩溃)。当对象放置在一个单元内时,这个问题就消失了。

我知道我可以将其留在单元中,但这会导致一些丑陋的代码,但希望可以避免。

有谁知道为什么会发生这种情况以及我如何避免它?

最佳答案

自 Delphi 2 发布(也许更早)以来,旧式 Delphi 对象已被破坏。当它们具有编译器管理类型的字段(例如字符串或动态数组)时,它们不能很好地继承。有a discussion about it 2004 年在 comp.lang.pascal.delphi.misc 上。这是重现它的代码:

type
  TBase = object
  public
    s: string;
  end;

  TDerived = object(TBase)
  end;

procedure test;
var
  obj: TDerived; //okay for TBase!
begin
  assert(obj.s = '', 'uninitialized dynamic variable');
end;

事实上,只有意外情况下,TBase 才可以,因为函数的序言代码是如何生成的。无论如何,在该函数中添加额外的代码都会使其崩溃。

确实,正如您所观察到的那样 - 旧式对象无法正确初始化。它们的字符串字段一开始并不是包含空字符串;而是一开始就包含空字符串。相反,它们保存垃圾,因此如果不使用像 FillChar 这样的东西,甚至不可能自己初始化它们。

这似乎是因为变量是本地变量。单位范围(“全局”)变量似乎工作正常。在单元范围内声明但仅由单元的初始化部分使用的变量,或在程序范围内仅在 DPR 文件的主开始结束 block 中使用的变量,将被编译器视为局部变量,因此它们不会设置为 all -bits-zero 就像他们的全局同行一样。当您将变量声明移至某个单元但继续在 DPR 文件中使用它时,它会提升为“全局”状态。

您的 TGUI_Element 类型有一个名为 DbgNamestring 成员,看起来这是类型层次结构中唯一的字符串字段。将其删除,或者将其更改为 ShortString,我敢打赌您的崩溃就会消失,至少会暂时消失。

关于delphi - 对象在主程序中崩溃,但在移动到单元时不会崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2147114/

相关文章:

delphi - 如何随机化不重复的名称?

c++ - 屏幕录像机

pascal - 如何在pascal中定义运算符

substring - 帕斯卡减法等效

Free Pascal Lazarus 1.0.2 (FPC 2.6.0) 中的 WinAPI 函数

multithreading - WaitForThreadTerminate超时时返回什么错误代码?

Pascal - 读/读函数杂质?

delphi - TWebBrowser 可以撤消或重做

delphi - 释放对象的无效指针操作

delphi - vcl组合框并不总是显示它有焦点