为什么 Delphi 编译器看不到我正在尝试释放接口?
我本周末编码时犯了一个小错误。
在下面的代码中,我创建了一个对象并将其转换为接口。后来,我尝试使用 FreeAndNil()
释放它;
type
IMyIntf = interface
[...]
end;
TMyClass = class(TInterfacedObject, IMyIntf)
[...]
end;
var
Myintf : IMyIntf;
begin
Myintf := TMyClass.Create;
[...] // Some process
FreeAndNil(Myintf); // CRASH !!!
end;
当然,程序在这一行崩溃了。 我完全理解这个问题,但我不明白的是为什么编译器不警告我?后面没有动态的东西,只是我试图释放一个接口!为什么它不给我写一个错误/警告?
背后是否有任何真正的解释,或者只是编译器的限制?
I've done a small mistake while coding this week-end.
In the following code, I'm creating an object and cast it to an interface. Later, I'm trying to free it with FreeAndNil()
;
type
IMyIntf = interface
[...]
end;
TMyClass = class(TInterfacedObject, IMyIntf)
[...]
end;
var
Myintf : IMyIntf;
begin
Myintf := TMyClass.Create;
[...] // Some process
FreeAndNil(Myintf); // CRASH !!!
end;
Of course, the program crash at this line.
I totally understand the issue, but what I don't understand is why the compiler doesn't warn me about it ? There is no dynamic things behind, it's just that I'm trying to free an interface !!! Why don't it write me an error / warning ?
Is there any real explanation behind or is it just a compiler limitation ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如您所知,正确的方法是编写
Myintf := nil
,或者只是让它超出范围。您问的问题是为什么编译器接受 FreeAndNil(Myintf) 并且在编译时不会抱怨。FreeAndNil
的声明是这是一个无类型参数。因此它会接受任何东西。您传递了一个接口,但您也可以传递一个整数、字符串等。
为什么设计者选择非类型化参数?好吧,他们需要使用
var
参数,因为FreeAndNil
的全部目的是释放对象并将对象引用设置为无。这无法通过目标对象的方法来完成,因此需要独立函数的
var
参数。您可能会想象您可以这样写,
因为所有对象都是
TObject
的后代。但这并不能完成任务。原因是传递给var
参数的对象必须与该参数的类型完全相同。如果以这种方式声明FreeAndNil
,则每次调用它时都必须强制转换为TObject
。因此,设计者决定,设计问题的最佳解决方案、最不坏的选择是使用无类型 var 参数。
As you know, the correct way to do this is to write
Myintf := nil
, or just to let it go out of scope. The question you ask is why the compiler acceptsFreeAndNil(Myintf)
and does not complain at compile time.The declaration of
FreeAndNil
isThis is an untyped parameter. Consequently it will accept anything. You passed an interface, but you could have passed an integer, a string and so on.
Why did the designers choose an untyped parameter? Well, they needed to use a
var
parameter since the whole purpose ofFreeAndNil
is to free the object and set the object reference tonil
. That can't be done by a method of the target object and so avar
parameter of a standalone function is needed.You might imagine that you could write
since all objects are descended from
TObject
. But this does not do the job. The reason being that the object you pass to avar
parameters must be exactly the type of that parameter. IfFreeAndNil
was declared this way you would have to cast toTObject
every time you called it.So, the designers decided that the best solution to the design problem, the least bad choice, is to use the untyped var parameter.