为什么 Delphi 编译器看不到我正在尝试释放接口?

发布于 2024-12-12 20:08:47 字数 541 浏览 0 评论 0原文

我本周末编码时犯了一个小错误。
在下面的代码中,我创建了一个对象并将其转换为接口。后来,我尝试使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你在看孤独的风景 2024-12-19 20:08:47

如您所知,正确的方法是编写 Myintf := nil,或者只是让它超出范围。您问的问题是为什么编译器接受 FreeAndNil(Myintf) 并且在编译时不会抱怨。

FreeAndNil 的声明是

procedure FreeAndNil(var Obj);

这是一个无类型参数。因此它会接受任何东西。您传递了一个接口,但您也可以传递一个整数、字符串等。

为什么设计者选择非类型化参数?好吧,他们需要使用 var 参数,因为 FreeAndNil 的全部目的是释放对象并将对象引用设置为 无。这无法通过目标对象的方法来完成,因此需要独立函数的 var 参数。

您可能会想象您可以这样写,

procedure FreeAndNil(var Obj: TObject);

因为所有对象都是 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 accepts FreeAndNil(Myintf) and does not complain at compile time.

The declaration of FreeAndNil is

procedure FreeAndNil(var Obj);

This 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 of FreeAndNil is to free the object and set the object reference to nil. That can't be done by a method of the target object and so a var parameter of a standalone function is needed.

You might imagine that you could write

procedure FreeAndNil(var Obj: TObject);

since all objects are descended from TObject. But this does not do the job. The reason being that the object you pass to a var parameters must be exactly the type of that parameter. If FreeAndNil was declared this way you would have to cast to TObject 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文