gpt4 book ai didi

Delphi 对象在 try block 内创建?

转载 作者:行者123 更新时间:2023-12-03 14:37:58 25 4
gpt4 key购买 nike

在 Delphi 7 中,对象的创建是这样的:

A := TTest.Create;
try
...
finally
A.Free;
end;

但是在 blog article Marco Cantù 说他们在 Embercadero 中使用

A1 := nil;
A2 := nil;
try
A1 := TTest.Create;
A2 := TTest.Create;
...
finally
A2.Free;
A1.Free;
end;

版本升级时tryfinally block 的逻辑是否发生了变化?第二个例子对我来说似乎是一个典型的错误!

最佳答案

两者都是可接受的模式。 没有发生改变。

首先让我们介绍一下您熟悉的那个以及为什么它是正确的。

{ Note that here as a local variable, A may be non-nil, but
still not refer to a valid object. }
A := TTest.Create;
try
{ Enter try/finally if and only if Create succeeds. }
finally
{ We are guaranteed that A was created. }
A.Free;
end;

在上面:如果 A 在 try 之后被赋值,那么 Create 可能会失败并跳转到这里。这将尝试从内存中未定义的位置释放对象。它可能导致访问冲突或不稳定的行为。 请注意,编译器还会在 A.Free; 上发出警告,指出 A 可能未初始化。这是因为可能会发生跳转由于构造函数中出现异常, A 之前分配给finally block 。

<小时/>

那么为什么 Marco 的代码可以接受呢?

A1 := nil; { Guarantees A1 initialised *before* try }
A2 := nil; { Guarantees A2 initialised *before* try }
try
A1 := TTest.Create;
A2 := TTest.Create;
...
finally
{ If either Create fails, A2 is guaranteed to be nil.
And Free is safe from a nil reference. }
A2.Free;
{ Similarly, if A1's Create fails, Free is still safe.
And if A1's create succeeds, but A2's fails: A1 refers to a valid
object and can be destroyed. }
A1.Free;
end;

请注意,Marco 的代码依赖于 Free() 行为的一些微妙之处。请参阅以下问答了解更多信息:

<小时/>

该技术背后的目的是避免嵌套的 try..finally block ,这可能会变得困惑。例如

A1 := TTest.Create;
try
A2 := TTest.Create;
try
{...}
finally
A2.Free;
end;
finally
A1.Free;
end;

Marco 的代码减少了嵌套级别,但需要本地引用的“预初始化”。

<小时/>

Victoria 提出了一个警告,如果 Marco 代码中 A2 的析构函数失败,则 A1 将不会被释放。这将是一定的内存泄漏。但是,我认为一旦任何析构函数失败:

  • 尚未成功完成;
  • so 可能已经至少泄漏了内存或资源;
  • 而且,您的系统的整体完整性也受到质疑。 如果“简单清理”失败:为什么、出了什么问题、 future 会导致什么问题?

所以我能提供的最好建议是:注意确保析构函数的正确性。

关于Delphi 对象在 try block 内创建?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48622311/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com