5

我在这样的小函数中使用 scoped_ptr。这样我就不必调用删除。这是这种用法的过度杀伤力吗?我的团队成员更喜欢原始指针和删除。如果碰巧在非常关键的路径中使用 scoped_ptr,使用它的成本是多少?这不应该是内联的并且完全等同于在优化的二进制文件中使用普通删除吗?

void myfunc()
{
  boost::scoped_ptr<myobj> objptr = someFactory::allocate();
  callsomeotherfunc(objptr.get());
}
4

4 回答 4

8

我不确定性能是否受到影响,但scoped_ptr在这里使用可以确保myfunc()异常安全:如果callsomeotherfunc()抛出异常,动态分配的内存仍将被释放。如果scoped_ptr未使用并且callsomeotherfunc()可以抛出,则该函数的结构必须与此类似:

void myfunc()
{
    myobj* objptr = someFactory::allocate();

    try
    {
        callsomeotherfunc(objptr);
        delete objptr;
    }
    catch (const some_exception&)
    {
        delete objptr;
        throw;
    }
}

这很容易出错,因为该函数的所有未来修改都需要确保delete objptr;在所有可能的退出点上调用它。

于 2012-04-27T12:54:25.367 回答
3

我不会scoped_ptr为此目的使用,而是unique_ptr在 C++11 和auto_ptr较旧的编译器中使用,这两者对于您的特定用例都是等效的。至于它是否是矫枉过正,不,不是,它是提供异常安全的唯一选择(比如说在代码中的任何东西myfunc或者callsomeotherfunc抛出,你希望内存被释放)。在性能方面,这三个选项等效于delete在未引发异常的情况下在函数末尾调用,并且比使用带有 a 的try/catchdelete在发生异常时重新引发异常更快。

此外,您似乎是从工厂分配的,在某些设计中,工厂将有一个deallocate需要调用的操作,而不是delete. 如果是这种情况,您可能会考虑使用不同的智能指针(来自标准,如果是释放内存的正确方法shared_ptr,这将是矫枉过正;或者您还可以提供删除器的一些不足)deletemanaged_ptr

于 2012-04-27T12:57:15.660 回答
0

不它不是。使用智能指针(例如异常安全和自动资源清理)的好处远高于使用智能指针创建、维护和销毁所需的几个额外字节内存和几个额外 CPU 时钟的性能损失。

于 2012-04-27T12:56:21.920 回答
0

我认为与 scoped_ptr 用法等效的是:

void myfunc()
{
  myobj* objptr = someFactory::allocate();
  try
  {
      callsomeotherfunc(objptr);
  }
  catch (...)
  {
      delete objptr;
      throw;
  }
  delete objptr;
}

我知道我更喜欢写哪个版本...

于 2012-04-27T12:58:42.827 回答