gpt4 book ai didi

delphi - 为什么使用过程来创建对象比使用函数更受欢迎?

转载 作者:行者123 更新时间:2023-12-03 14:35:26 24 4
gpt4 key购买 nike

这类似于 this question 。我问:“为什么?”至 the most popular response但我不知道还有人会再看它。至少没有及时。

无论如何,我的问题是关于将创建对象的责任委托(delegate)给函数或过程的最佳实践,而不会导致内存泄漏。看来是这样的:

procedure FillObject(MyObject: TMyObject; SomeParam: Integer);
begin
//Database operations to fill object
end;

procedure CallUsingProcedure();
var
MyObject: TMyObject;
begin
MyObject = TMyObject.Create();
try
FillObject(MyObject, 1);
//use object
finally
MyObject.Free();
end;
end;

优于此:

function CreateMyObject(DBID: Integer): TMyObject;
begin
Result := TMyObject.Create();
try
//Database operations to fill object
except on E: Exception do
begin
Result.Free();
raise;
end;
end;
end;

procedure CallUsingFunction();
var
MyObject: TMyObject;
begin
MyObject = CreateMyObject(1);
try
//use object
finally
MyObject.Free();
end;
end;

为什么?

我对 Delphi 比较陌生,以前大部分时间都使用 Java 和 PHP,以及 C++,尽管程度较低。直觉上,我倾向于函数方法,因为:

  • 它将对象创建代码封装在函数中,而不是每当我想使用该过程时单独创建对象。
  • 我不喜欢改变参数的方法。它通常没有记录下来,并且会使跟踪错误变得更加困难。
  • 含糊其辞,但不可否认,它对我来说只是“闻起来”很糟糕。

我并不是说我是对的。我只是想了解为什么社区选择这种方法,以及是否有充分的理由让我做出改变。

编辑:评论中对@E-Rock 的引用是我(Eric G)。我更改了我的显示名称。

最佳答案

一个问题是 Ken White 所写的:您向函数的用户提供了一个他或她必须释放的对象。

过程的另一个优点是您可以传递层次结构的多个对象,而创建此类对象的函数总是生成相同的对象。例如

procedure PopulateStrings(Strings: TStrings);

对于该过程,您可以传递任何类型的TStrings,无论是TMemoTListBoxTComboBoxItems 或简单的独立 TStringList。如果你有一个函数:

function CreateStrings: TStrings;

你总是得到相同类型的对象(具体哪个对象是未知的,因为TStrings抽象,所以你可能会得到一个TStringList em>),并且必须Assign()将内容分配给要修改的TStrings。 IMO,程序是首选

此外,如果您是该函数的作者,则无法控制您创建的对象是否被释放或何时被释放。如果您编写一个过程,那么这个问题就从您手中解决了,因为用户提供了该对象,并且它的生命周期与您无关。而且您不必知道对象的确切类型,它必须只是该类或参数的后代。 IOW,这对于该函数的作者来说也好多了。

出于所有给出的原因,在我看来,从函数返回对象很少是一个好主意。仅修改对象的过程对对象没有依赖性,也不会为用户创建任何依赖性。

FWIW,另一个问题是如果您从 DLL 中执行此操作。返回的对象使用DLL的内存管理器,并且它指向的VMT也在DLL中。这意味着在用户代码中使用 asis 的代码无法正常工作(因为 isas使用 VMT 指针检查类标识)。如果用户必须将他的对象传递给过程,则不会出现该问题。

更新

正如其他人评论的那样,将对象传递给 DLL 也不是一个好主意。非虚函数会调用DLL内部的函数并使用它的内存管理器,这也会带来麻烦。并且 isas 在 DLL 中也无法正常工作。 因此,不要将对象传入或传出 DLL。这符合 DLL 只能使用 POD type 的格言。参数(或复合类型——数组、记录——仅包含 POD 类型)或 COM 接口(interface)。 COM 接口(interface)也应该只使用相同类型的参数。

关于delphi - 为什么使用过程来创建对象比使用函数更受欢迎?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7423604/

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