【问题标题】:Can't check if class has been created [duplicate]无法检查是否已创建类[重复]
【发布时间】:2019-12-14 10:26:57
【问题描述】:

我在 delphi 中创建了一个类。看起来是这样的

    TGoJsNode = class(TPersistent)
      private
        _id: Integer;
        Key: Integer;
        Text: String;

        constructor Create;
    end;

我需要检查何时有效地创建了这个类(使用了构造函数)。例如,当我这样做时:

var
  x: TGoJsNode;
begin
  if Assigned(x) then
     // Will return True
     showmessage('created');

  if x = nil then   
     // Will also return True
     showmessage('created');
end;

这两个测试的结果都是 true,而事实上我并没有创建 x。在我看来,当我创建它时,x 应该只在分配的测试中产生 true,如下所示:

procedure TForm1.Button18Click(Sender: TObject);
var
  x: TGoJsNode;
begin
  x := TGoJsNode.Create;
end;

我观察到的另一件奇怪的事情是私有数值变量具有随机值,而字符串一个是空的。所有的类都在同一个单元文件中。有什么想法吗?

【问题讨论】:

    标签: delphi


    【解决方案1】:

    一切都按设计和预期运行。问题是您的期望是基于不正确的理解。

    非托管局部变量是未初始化的,因此它们的值是未定义的,直到它们被显式初始化。所以你的变量 x 在你初始化之前可以有任何值。

    Assigned() 函数测试指针变量是否为nil。在初始化变量之前,Assigned() 返回的值是未定义的。有关Assigned() 的更广泛讨论,请参阅此answer

    不初始化局部变量的规则的一个例外是托管类型。它们总是被初始化。字符串是托管类型,这解释了为什么您会看到它们始终为空。数值类型不受管理,因此不会自动初始化。

    其他托管类型包括移动平台上的动态数组、接口、变体、匿名方法和 ARC 类。此外,包含托管类型的结构化类型(例如实例记录和数组)本身也成为托管类型。

    另一个细微差别是全局变量和类成员是默认初始化的。只有局部变量可能不会被初始化。

    【讨论】:

    • 我已经记不清我的问题和你的答案被引用的次数了。我什至记得你在你的用户资料中提到过。
    • @RemyLebeau 感谢您的编辑。我对随机这个词有非常小的问题。尽管它看起来是随机的,但该值完全可以是确定性的,并且由早期代码留下的堆栈内容决定。我不想在这里使用随机这个词,因为接下来的问题是,每次我运行函数时值都是一样的,但是你说它是随机的.....
    • 虽然字符串总是有效的,但我发现它们不一定是空的。
    • @Golez 它们总是被初始化为空字符串。如果您发现一个具有非空值的值,则将代码中的某些内容分配给该变量。
    • 谢谢@DavidHeffernan,这些链接对我帮助很大
    猜你喜欢
    • 2021-10-26
    • 1970-01-01
    • 2015-11-01
    • 1970-01-01
    • 2015-08-11
    • 2012-02-05
    • 2017-11-17
    • 1970-01-01
    • 2017-03-09
    相关资源
    最近更新 更多