静态对象上的shared_ptr好吗?

Are shared_ptr on static objects good?

本文关键字:ptr 好吗 shared 对象 静态      更新时间:2023-10-16

我想知道静态对象上的智能指针是否合理。例如,假设我有一些静态资源,并希望将对静态资源的引用传递给需要这些资源才能使用的其他一些对象。

一种方法是使用指向该资源的 RAW 指针。但是现在我想知道智能指针(shared_ptr)是否是更好的方法,如果是这样,如何正确执行此操作。(智能指针也应该是静态的吗?

问题的背景:如果不再有持有智能指针的对象,智能指针指向的静态对象将被释放(这不是最好的主意......

一个例子(在运行时结束时以崩溃告终):

struct SomeType {
  SomeType() { cout << "ctor..." << endl; }
  ~SomeType() { cout << "dtor..." << endl; }
  void sayHello() { cout << "Hello!" << endl; }
};

void someFunction(shared_ptr<SomeType> smartPointer) {
  smartPointer->sayHello();
}
static SomeType st;
static shared_ptr<SomeType> pt{ &st };
void anotherFunction() {
  someFunction(pt);
}
int main() {
  anotherFunction();
  cin.get();
}

以下两行无效。

static SomeType st;
static shared_ptr<SomeType> pt{ &st };

pt在进程生命周期结束时被销毁时,它将delete st . st从未分配过匹配的new。这是未定义的行为。

shared_ptr对于管理共享对象的复杂生存期很有用,而static对象的生存期非常简单。使用shared_ptr来管理static对象是不正确的,这样做没有任何好处。

假设我(作为类作者)不知道对象是静态的还是动态的

需要不可知的代码绝对应该使用 shared_ptr<T> .

您提供的此代码无效,因为它会导致删除具有静态生存期的对象。

static SomeType st;
static shared_ptr<SomeType> pt{ &st };

这很好:

static SomeType st;
static shared_ptr<SomeType> pt{ std::shared_ptr<SomeType>{}, &st };

并且该pt可以与"正常"shared_ptr实例互换使用。 std::shared_ptr在这方面特别方便,因为删除器的存在与否不会影响指针类型(相比之下,std::unique_ptr<T, custom_deleter<T>>std::unique_ptr<T, default_deleter<T>>是不同的类型)

指定不执行任何操作的删除程序的此方法和其他方法在以下位置进行了描述:

  • 你如何使标准::shared_ptr不调用删除()