在简单的情况下使用scoped_ptr是不是矫枉过正

Is it an overkill to use scoped_ptr in simple cases?

本文关键字:ptr 是不是 矫枉过正 scoped 简单 情况下      更新时间:2023-10-16

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

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

我不确定性能是否受到影响,但在此处使用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;

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

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

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

我认为相当于

scoped_ptr用法是:

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

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