调用`shared_ptr.get()`vs copy-initialization,有什么区别?

时间:2014-06-07 12:37:17

标签: c++ shared-ptr

第一版打印use_count = 2;

shared_ptr<int> s{make_shared<int>(15)};
  auto b = s;
  cout<<s.use_count()<<endl;
  auto c = s.get();
  cout<<s.use_count()<<endl;
  cout<<*c<<endl;  

第二版use_count = 3;

shared_ptr<int> s{make_shared<int>(15)};
  auto b = s;
  cout<<s.use_count()<<endl;
  auto c = s;
  cout<<s.use_count()<<endl;
  cout<<*c<<endl;  

问题:

  • 为什么两个版本之间的行为不同?

1 个答案:

答案 0 :(得分:1)

简介

每次复制 shared_ptr 时, use-count 都会增加,因为您有一个额外的句柄来跟踪被跟踪的基础资源。

为了获取底层指针的值, shared_ptr 有一个名为get的成员函数。此函数将返回被跟踪资源的地址,它将创建一个额外的 shared_ptr 跟踪相同的指针。


潜在危险

在您的第一个代码段中,您实际上有2个 shared_ptr 实例引用相同的资源,但在后者中您有三个。

区别在于;

  • auto a = s将创建s的副本,a的类型为s的类型( shared_ptr
  • auto b = s.get ()会使用b管理的跟踪资源的地址初始化s,因此它将是原始指针

如果您不确切知道自己在做什么,调用.get ()可能会有危险,如下面的代码段所示。

int * ptr = nullptr;

{
  std::shared_ptr<int> sp { make_shared<int> (15) };
  ptr = sp.get ();
}

std::cout << *ptr << std::endl; // (A), dangling pointer

在我们的嵌套范围内,我们创建了一个名为sp shared_ptr ,我们要求它跟踪int 动态存储时间我们致电make_shared

我们通过调用int获取此sp.get ()的地址,并将其分配给ptr

sp的范围结束时,sp将释放所管理的资源,因为不再有* shared_ptr * s引用它。

通过尝试打印*ptr的值,我们在( A )中调用未定义的行为,因为该值不可用,它是随着sp的毁灭而被摧毁。