4

在编程时,我多次遇到以下设计选择:用户创建一个对象并将其传递给其他对象,该对象在第二阶段以某种方式进行处理。

例如,您可以想象一个光线追踪器。用户创建具有某些属性的球体并调用raytracer.addTraceable(sphere)。现在,我可以想到三种方法来做到这一点。

  1. 光线追踪器负责释放分配给球体对象的内存
  2. 用户需要释放分配给球体对象的内存。
  3. 光线追踪器只复制球体对象,用户和光线追踪器都释放它们的本地副本。

一般来说,在这种情况下最好的设计选择是什么?除了我提到的那些(不包括智能指针)之外,还有其他选择吗?

PS:在使用面向对象的方法时,我在纯 C 中遇到了同样的问题。

4

3 回答 3

6

RAII的一致使用使这成为一个争论点。使用智能指针,例如std::shared_ptr对象为所有指针所拥有,并在最后一个指针被销毁后被删除。

C 并没有真正方便的方式来表达 RAII 习语。

于 2013-10-07T03:49:11.297 回答
2

您似乎意识到智能指针会为您解决问题,但是您出于未解释的原因而将其解雇。(也许是因为你的代码真的必须同时适用于 C 和 C++?)

如果sphere对象由raytracer对象管理,那么逻辑上它会获得对象的所有权。但是,您遗漏了一个适合此应用程序的选择:

  • 用户提供要添加到的对象的属性,raytracer然后负责创建和销毁对象。

then 变成了类似工厂的raytracer东西,而 properties 对象就像是 builder。

于 2013-10-07T03:28:27.890 回答
1

从设计的角度来看,所有三种方式都可能是正确的,但总有优缺点:

  1. 更改所有权以 auto_ptr 的形式存在于 C++ 中。缺点是代码维护,例如在光线跟踪器中,您必须始终牢记对象是如何分配的,从哪个堆分配的。如果光线追踪器是在具有单独堆的 3rd 方 dll 中实现的,它将在调试模式下失败并且在释放时会发生内存泄漏。
  2. 如果光线追踪器用户必须释放内存 - 它必须跟踪光线追踪器,这意味着它必须拥有所有权,这取决于实现它可能会增加不必要的代码复杂性。
  3. 复制对象将是一个完美的解决方案,除非原始球体对象的更改必须在光线跟踪器中进行跟踪或复制会影响性能或根本不可能。
于 2013-10-07T03:36:45.230 回答