谁应该拥有指针

时间:2013-10-07 03:17:01

标签: c++ c pointers memory-management

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

举个例子,你可以想象一个光线跟踪器。用户创建具有特定属性的球体并调用raytracer.addTraceable(sphere)。现在,有三种方法我可以想到这样做。

  1. 光线跟踪器负责释放分配给球体对象的内存
  2. 用户需要释放分配给sphere对象的内存。
  3. 光线跟踪器只复制球体对象,用户和光线跟踪器都会释放它们的本地副本。
  4. 在这种情况下,一般来说最好的设计选择是什么?除了我提到的那些(不包括智能指针)之外还有其他选择吗?

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

3 个答案:

答案 0 :(得分:6)

RAII的一致使用使这成为一个有争议的问题。使用诸如std::shared_ptr之类的智能指针,该对象由指针的所有拥有,并在最后一个指针被销毁后被删除。

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

答案 1 :(得分:2)

您似乎意识到智能指针可以为您解决问题,但是由于您没有解释的原因,您正在解雇它。 (也许是因为你的代码真的必须适用于C和C ++?)

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

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

然后raytracer变成类似工厂的东西,属性对象类似于构建器。

答案 2 :(得分:1)

从设计的角度来看,这三种方式都是正确的,总有利弊:

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