代码复习问题 - 我应该允许将auto_ptr作为参数传递吗?

Gar*_*wen 5 c++ coding-style auto-ptr

请考虑我最近在代码库中看到的以下示例代码:

void ClassA::ExportAnimation(auto_ptr<CAnimation> animation)
{
... does something
}

// calling method:
void classB::someMethod()
{
  auto_ptr<CAnimation> animation (new CAnimation(1,2));
  ClassA classAInstance;
  classAInstance.ExportAnimation(animation)
  ... do some more stuff
}
Run Code Online (Sandbox Code Playgroud)

我不喜欢这样 - 宁愿写它:

void ClassA::ExportAnimation(CAnimation* animation)
{
    ... does something
}

// calling method:
void classB::someMethod()
{
  auto_ptr<CAnimation> animation (new CAnimation(1,2));
  ClassA classAInstance;
  classAInstance.ExportAnimation(animation.get())
  ... do some more stuff
}
Run Code Online (Sandbox Code Playgroud)

但这确实是一个问题?

Dav*_*eas 4

这一切都取决于它ExportAnimation是什么以及如何实施。

它是否只在调用期间使用该对象,然后就离开它?

然后转换为引用并传递真实的引用。不需要传递成员资格,并且参数不是可选的,因此就void ExportAnimation( CAnimation const & )足够了。优点是从接口中可以清楚地看出该方法不存在内存管理问题,它只会使用传递的对象并保持原样。在这种情况下,传递原始指针(如您建议的代码中)比传递引用要糟糕得多,因为不清楚是否ExportAnimation负责删除传入的对象。

它会保留该对象以供以后使用吗?

如果函数启动一个线程在后台导出动画,则可能会出现这种情况。在这种情况下,必须明确参数的生命周期必须超出调用的持续时间。shared_ptr这可以通过在函数内和函数外使用来解决,因为它们传达了对象是共享的,并且将根据需要的含义保持活动状态。否则您实际上可以转让所有权。

在后一种情况下,如果执行所有权转移,那么初始代码就可以了——签名在所有权转移中是明确的。否则,您可以选择记录行为,更改为原始指针并通过调用显式传输ExportAnimation( myAnimation.release() )

您添加了一些问题作为对另一个答案的评论:

我真的可以看到该对象在方法调用后不再存在吗?

调用者auto_ptr在调用中被重置为 0,因此任何取消引用都将成为错误,并将在您尝试的第一个测试中被标记。

我需要查看头文件以查看参数类型是 auto_ptr 而不是普通指针。

您不需要查看标头...只需尝试传递原始指针,编译器就会告诉您它需要auto_ptr<>--There 没有从原始指针到auto_ptr.

我希望该对象一直存在,直到 auto_ptr 超出范围。

auto_ptr与 不同的是,该标准boost::scope_ptr没有这种语义。对象的所有权可以被释放或传递给 other auto_ptr,因此假设一个对象在 的auto_ptr整个范围内都存在,这auto_ptr本身就是不好的。