Delphi 如果我在“with”子句中创建了一个对象,我还需要释放它吗?

Delphi 如果我在“with”子句中创建了一个对象,我还需要释放它吗?,delphi,delphi-7,pascal,with-statement,Delphi,Delphi 7,Pascal,With Statement,在我的资料中,我经常看到并使用如下结构: with TSQLDataSet.Create(nil) do try //Dosomething, get a result from a query. finally Free; end; 但我也经常看到建筑: with TSQLDataSet.Create(nil) do begin //Dosomething, get a result from a query. end; 如果使用with CONSTRUCTIO

在我的资料中,我经常看到并使用如下结构:

with TSQLDataSet.Create(nil) do try
  //Dosomething, get a result from a query.    
finally
  Free;
end;
但我也经常看到建筑:

with TSQLDataSet.Create(nil) do begin
  //Dosomething, get a result from a query.    
end;

如果使用with CONSTRUCTION创建对象,我需要释放它们吗?还是with块结束时自动释放?

您需要手动释放对象。在with块的末尾自动释放它们并不是真的。这在一般情况下适用。如果TSQLDataSet有什么特殊之处,我不知道。

您需要手动释放该对象。在with块的末尾自动释放它们并不是真的。这在一般情况下适用。如果TSQLDataSet有什么特别之处,我不知道。

您需要释放

因为Class.Create只是一个表达式,Delphi无法知道结果值来自哪个表达式

你可以直接读VCL源代码——总是有显式的。免费的

您可以考虑非对象示例:

var r: record .... end;
with r do begin
...
end;
如果Delphi试图在末尾释放所有东西,那么它会尝试释放非对象吗

with SomeObjectFactory.GetMeAnObject do begin
...
end;
在这里,您不是通过构造函数创建对象,而是通过一些函数创建对象。此函数与TLabel.Font或TDataSet.FieldByName没有区别。 Delphi是否应该在这里释放它

为了避免危险的猜测,并保持一致性,使用就是使用。它只是一个别名。没别的了。它早在1974年就设计好了,它没有使用x{..}构造克隆最新的.Net/Scala功能

你可能看到的是这样的

with TForm.Create(Application) do ...;
with TLabel.Create(MainForm.Panel1) do ...;
这是非常不同的-它插入新创建的控件作为属于所有者。所有者将在释放自己时释放其所有的组件。但这并不使用Createnil。当它仍然存在时,在with块中,您将看到一些显式调用,将对象绑定到某个容器/父对象,尽管在.Create和binding之间出现异常时,这是非常脆弱的。

您需要释放

因为Class.Create只是一个表达式,Delphi无法知道结果值来自哪个表达式

你可以直接读VCL源代码——总是有显式的。免费的

您可以考虑非对象示例:

var r: record .... end;
with r do begin
...
end;
如果Delphi试图在末尾释放所有东西,那么它会尝试释放非对象吗

with SomeObjectFactory.GetMeAnObject do begin
...
end;
在这里,您不是通过构造函数创建对象,而是通过一些函数创建对象。此函数与TLabel.Font或TDataSet.FieldByName没有区别。 Delphi是否应该在这里释放它

为了避免危险的猜测,并保持一致性,使用就是使用。它只是一个别名。没别的了。它早在1974年就设计好了,它没有使用x{..}构造克隆最新的.Net/Scala功能

你可能看到的是这样的

with TForm.Create(Application) do ...;
with TLabel.Create(MainForm.Panel1) do ...;

这是非常不同的-它插入新创建的控件作为属于所有者。所有者将在释放自己时释放其所有的组件。但这并不使用Createnil。当它仍然存在时-然后在with块中,您将看到一些显式调用,将对象绑定到某个容器/父对象,尽管这在.Create和binding之间出现异常时非常脆弱。

Delphi object pascal,C,C++和许多第三代语言都不是托管代码,它负责将内存回收到程序员。因此,无论哪种情况,您都必须确保获得的内存被释放到代码中的任何地方

您给出的第一个示例假设您创建的对象在end语句之后不需要处于活动状态。第二个示例假定对象已创建并传递给另一个对象,以便在End语句之后使用。因此,使用对象应该处理内存的释放


在托管代码环境(如Java VM或.Net应用程序)中,内存由环境处理。当环境不适合分配的内存块时,环境就感觉到,并且当它适合环境时释放它。

< Pel> Delphi对象Pascal、C、C++和许多第三代语言,它们不是托管代码,它负责将内存回收到程序员。因此,无论哪种情况,您都必须确保获得的内存被释放到代码中的任何地方

您给出的第一个示例假设您创建的对象在end语句之后不需要处于活动状态。第二个示例假定对象已创建并传递给另一个对象,以便在End语句之后使用。因此,使用对象应该处理内存的释放


在托管代码环境(如Java VM或.Net应用程序)中,内存由环境处理。当没有对已分配内存块的引用时,环境会进行感知,并在适合环境时释放内存块。

我严重怀疑您是否“经常”看到后一个版本。@Andreas-好的观点。但若WITHBODY将对象连接到某个容器,那个么这是可能的。或者不是零

构造函数参数如果你拥有它,你必须释放它,或者将所有权传给他人。我严重怀疑你是否经常看到后一个版本。@Andreas-很好。但若WITHBODY将对象连接到某个容器,那个么这是可能的。或者使用not nil构造函数参数如果您拥有它,您必须释放它,或者将所有权传递给他人。我已经拓宽了编程语言的视野,并阅读了有关使用构造函数的内容。然后你在自己的代码库中创建构造,但是没有显式的free,所以我想,这是正确的还是错误的。在进一步测试之后,确实需要显式释放使用with语句创建的对象。如果你不这样做,它会一直占据你的记忆。但它们并没有被报告为内存泄漏。是的,Pascal的跛脚不能与Python的相混淆with@David我不会说它是跛子。有限的,对。但并不是每一个有限的功能都是跛脚的。@Arioch't与其说它是有限的,不如说它的功能太强大了great@David真正地我想知道。。。那么,您打算如何在不有效消除功耗的情况下降低功耗呢?我已经拓宽了编程语言的视野,并阅读了有关使用构造的内容。然后你在自己的代码库中创建构造,但是没有显式的free,所以我想,这是正确的还是错误的。在进一步测试之后,确实需要显式释放使用with语句创建的对象。如果你不这样做,它会一直占据你的记忆。但它们并没有被报告为内存泄漏。是的,Pascal的跛脚不能与Python的相混淆with@David我不会说它是跛子。有限的,对。但并不是每一个有限的功能都是跛脚的。@Arioch't与其说它是有限的,不如说它的功能太强大了great@David真正地我想知道。。。那么,如何在不有效删除的情况下降低功耗呢?这比托管代码要复杂得多。如果存在表示系统资源的对象,那么它们的生存期不能留给GC。例如,具有句柄的文件对象。因此.NETIDisposable等等。数据库连接也是如此,它比托管代码更复杂。如果存在表示系统资源的对象,那么它们的生存期不能留给GC。例如,具有句柄的文件对象。因此.NETIDisposable等等。数据库连接也是如此。