“免费”是什么意思?在德尔福做什么?
我在此处找到了以下代码片段:
with TClipper.Create do
try
AddPolygon(subject, ptSubject);
AddPolygon(clip, ptClip);
Execute(ctIntersection, solution);
finally
free;
end
只是好奇,free<有什么作用? /code> 语句/函数(在
finally
和 end
之间)在这里做什么?谷歌没有提供帮助。
I found the following code snippet here:
with TClipper.Create do
try
AddPolygon(subject, ptSubject);
AddPolygon(clip, ptClip);
Execute(ctIntersection, solution);
finally
free;
end
Just curious, what does the free
statement/function (between finally
and end
) do here? Google did not help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
如果“with”像一些海报所暗示的那样邪恶,请他们解释一下
1. 为什么 Borland 创建这种语言结构,以及
2. 为什么他们(Borland/Embarcadero/CodeGear)在自己的代码中广泛使用它?
虽然我当然理解一些 Delphi 程序员不喜欢“with”,并且承认一些用户滥用它,但我认为说“你不应该使用它”是愚蠢的。
angusj - 违规代码的作者:)
If "with" is as evil as some posters are suggesting, could they please explain
1. why Borland created this language construct, and
2. why they (Borland/Embarcadero/CodeGear) use it extensively in their own code?
While I certainly understand that some Delphi programmers don't like "with", and while acknowledging that some users abuse it, I think it's silly to say "you shouldn't use it".
angusj - author of the offending code :)
任何动态创建的对象都必须调用free来释放对象创建时使用后分配的内存。 TClipper 对象是一个桌面内容创建、捕获和管理工具。所以它是某种 Delphi 与 Clipper 的连接对象。 create(对象创建)在try finaly end;语句中处理,这意味着,如果与 Clipper 的连接不成功,则对象 TClipper 将不会被创建,也不能被创建。在 try Finaly end; 语句之后释放。
Any dinamicly created object must call free to free at object creation alocated memory after use. TClipper object is a desktop content creation, capture and management tool. So it is some kind of Delphi connection object with Clipper. The create (object creation) is handled in try finaly end; statment what mean, if connection with Clipper isn't successful the object TClipper will not be created and can not be freed after after of try finaly end; statement.
我对 Delphi 一无所知,但我认为它正在释放 TClipper 使用的资源,就像 C# 中的 using 语句一样。这只是一个猜测......
I don't know anything about Delphi but I would assume that it is releasing the resources used by TClipper much like a using statement in C#. That is just a guess....
Free调用对象的析构函数,释放对象实例占用的内存。
Free calls the destructor of the object, and releases the memory occupied by the instance of the object.
它是对 TObject.Free 的调用,其基本定义为:
它在
with
语句中创建的未命名 TClipper 对象上执行。这是一个很好的例子,说明了为什么不应该使用
with
。它往往会使代码更难阅读。It's a call to TObject.Free, which is basically defined as:
It's being executed on the unnamed TClipper object created in the
with
statement.This is a very good example of why you shouldn't use
with
. It tends to make the code harder to read.该代码
是
TClipper.Create
的简写,创建一个TClipper
类型的对象,并返回该对象,以及with
语句,其工作方式与大多数情况一样语言,允许您访问此 TClipper 对象的方法和属性,而无需使用NameOfObject.MethodOrProperty
语法。(一个更简单的例子:
可以简化为
)
但是在您的情况下,您永远不需要将 TClipper 对象声明为变量,因为您创建了它并且可以通过
with
访问它的方法和属性构造。因此,您的代码几乎相当于
第一行
Clipper := TClipper.Create
,创建一个TClipper
对象。以下三行处理该对象,然后 Clipper.Free 销毁该对象,释放 RAM,还可能释放由 TClipper 对象使用的 CPU 时间和操作系统资源。但上面的代码并不好,因为如果在
AddPolygon
或Execute
中发生错误(创建异常),那么Clipper.Free
永远不会被调用,所以你会发生内存泄漏。为了防止这种情况,Delphi 使用try...finally...end
结构:finally
和end
之间的代码保证运行,即使创建了异常,并且即使您在try
和finally
之间调用Exit
。Mason 的意思是,有时,由于标识符冲突,
with
构造可能会成为……大脑中的油漆。例如,考虑一下如果您将其写在
with
构造中,即如果您这样写,那么您可能会感到困惑。事实上,大多数情况下
Caption :=
会更改当前表单的标题,但现在,由于with
语句,它将更改 MyObject 的标题。更糟糕的是,如果
MyObject 没有
Caption
属性,而您忘记了这一点(并认为该属性称为Caption
),那么甚至不会编译,而
只会编译很好,但它不会达到您的期望。
此外,像 in 那样构造
或嵌套
with
语句可能会产生很多冲突。
为了捍卫
With
语句,我注意到几乎有一个共识(至少在这个线程中):
with
语句弊大于利。尽管我意识到潜在的混乱,并且已经陷入其中几次,但我不能同意。仔细使用with语句可以使代码看起来更漂亮。这减少了由于“barfcode”而造成混乱的风险。例如:
Compare
with
绝对没有混淆的风险,而且我们不仅在最后一种情况下保存了临时变量 - 它也更具可读性。
或者这个非常非常标准的代码怎么样:
混淆的风险到底在哪里?从我自己的代码中,我可以给出数百个
with
语句的示例,所有这些都简化了代码。此外,如上所述,只要您知道自己在做什么,使用
with
就完全没有风险。但是,如果您想将with
语句与上例中的MyObject
一起使用,该怎么办:然后,在with
语句内,Caption
等于MyObject.Caption
。那么如何更改表单的标题呢?简单的!with 的另一个有用之处是处理需要花费大量时间执行的属性或函数结果时。
要使用上面的 TClipper 示例,假设您有一个 TClipper 对象列表,其中包含一个 slow 方法,该方法返回特定 TabSheet 的剪辑器。
理想情况下,您应该只调用此 getter 一次,因此您可以使用显式局部变量,也可以使用 with 来使用隐式局部变量。
OR
在这种情况下,任何一种方法都可以,但在某些情况下,通常在复杂的条件中, with 可以更清晰。
或
最终是个人品味问题。我通常只会使用范围非常严格的with,并且从不嵌套它们。通过这种方式使用,它们是减少条形码的有用工具。
The code
is shorthand for
TClipper.Create
creates an object of typeTClipper
, and returns this, and thewith
statement, which works as in most languages, lets you access the methods and properties of this TClipper object without using theNameOfObject.MethodOrProperty
syntax.(A simpler example:
can be simplified to
)
But in your case, you never need to declare a TClipper object as a variable, because you create it and can access its methods and properties by means of the
with
construct.So your code is almost equivelant to
The first line,
Clipper := TClipper.Create
, creates aTClipper
object. The following three lines work with this object, and thenClipper.Free
destroys the object, freeing RAM and possibly also CPU time and OS resources, used by theTClipper
object.But the above code is not good, because if an error occurrs (an exception is created) within
AddPolygon
orExecute
, then theClipper.Free
will never be called, and so you have a memory leak. To prevent this, Delphi uses thetry...finally...end
construct:The code between
finally
andend
is guaranteed to run, even if an exception is created, and even if you callExit
, betweentry
andfinally
.What Mason means is that sometimes the
with
construct can be a paint in the ... brain, because of identifier conflicts. For instance, considerIf you write this inside a
with
construct, i.e. if you writethen you might get confused. Indeed, most often
Caption :=
changes the caption of the current form, but now, due to thewith
statement, it will change the caption of MyObject instead.Even worse, if
and MyObject has no
Caption
property, and you forget this (and think that the property is calledCaption
), thenwill not even compile, whereas
will compile just fine, but it won't do what you expect.
In addition, constructs like
or nested
with
statements as incan produce a lot of conflicts.
In Defence of The
With
StatementI notice that there almost is a consensus (at least in this thread) that the
with
statement is more evil than good. Although I am aware of the potential confusion, and have fallen for it a couple of times, I cannot agree. Careful use of thewith
statement can make the code look much prettier. And this lessens the risk of confusion due to "barfcode".For example:
Compare
with
There is absolutely no risk of confusion, and not only do we save a temporaray variable in the last case - it also is far more readable.
Or what about this very, very, standard code:
Exactly where is the risk of confusion? From my own code I could give hundreds of more examples of
with
statements, all simplifying code.Furthermore, as have been stated above, there is no risk of using
with
at all, as long as you know what you are doing. But what if you want to use awith
statement together with theMyObject
in the example above: then, inside thewith
statement,Caption
is equal toMyObject.Caption
. How do you change the caption of the form, then? Simple!Another place where with can be useful is when working with a property or function result that takes a non-trivial amount of time to execute.
To work with the TClipper example above, suppose that you have a list of TClipper objects with a slow method that returns the clipper for a particular TabSheet.
Ideally you should only call this getter once, so you can either use an explicit local variable, or an implicit one using with.
OR
In a case like this, either method would do, but in some circumstances, typically in complex conditionals a with can be clearer.
OR
In the end is is matter of personal taste. I generally will only use a with with a very tight scope, and never nest them. Used this way they are a useful tool to reduce barfcode.