制作shared_ptr的副本会发生什么?

时间:2017-07-31 08:46:34

标签: c++ c++11 shared-ptr

我想了解当shared_ptr被分配给另一个时,shared_ptr中托管对象的引用计数会受到影响。

我在 C ++入门,第5版中看到以下声明:

  

例如,与shared_ptr关联的计数器递增   当... 我们将它用作作业的右手操作数 ...   当我们为其分配新值时,计数器会递减   shared_ptr的 ...

作为一个例子,它显示在那里:

auto p = make_shared<int>(42); // object to which p points has one user

auto q(p); // p and q point to the same object
           // object to which p and q point has two users

auto r = make_shared<int>(42); // int to which r points has one user
r = q; // assign to r, making it point to a different address
       // increase the use count for the object to which q points
       // reduce the use count of the object to which r had pointed
       // the object r had pointed to has no users; that object is automatically freed

当我运行类似的代码时,以上不是我的观察:

代码:

#include<iostream>
#include<memory>

int main()
{
  std::shared_ptr<int> sh1 = std::make_shared<int>(1);
  std::shared_ptr<int> sh2 = std::make_shared<int>(2);

  sh2 = sh1;

  std::cout << "sh1 use count: " << sh1.use_count() << std::endl;
  std::cout << "sh2 use count: " << sh2.use_count() << std::endl;

  return 0;
}
  

输出

     

sh1使用次数:2

     

sh2使用次数:2

use_count的{​​{1}}如何也是2?根据上面提到的文字,它不应该是0吗?我在这里错过了什么吗?

3 个答案:

答案 0 :(得分:10)

首先,您有sh1.use_count=1sh2.use_count=1。现在,当您使用sh2=sh1进行分配时,会发生以下情况:

  1. sh2计数器减1,因为sh2shared_ptr)将采用另一个指针
  2. sh2.use_count=0开始,其指针下的对象int(2)将被销毁。
  3. 现在您已将sh2分配给属于sh1的新对象,因此其计数器增加1,因此:sh2.use_count=2,当然还有{{1}因为两个sh1.use_count=2对象都指向同一个对象,即shared_ptr

答案 1 :(得分:1)

我认为这种误解的发生是因为您认为计数器与指向所拥有对象的指针一起存储在shared_ptr实例中。但实际上,shared_ptr的实例仅包含指向内部存储对象的指针,该内部存储对象包含引用计数器和指向拥有对象的指针。因此,当您执行sh2 = sh1;分配时,您需要sh2引用与sh1相同的内部存储对象,以便sh1sh2报告的计数器值来自同一个来源。

答案 2 :(得分:0)

最初我们有

sh1.use_count =1 and 
sh2.use_count = 1
*sh1  = 1 and 
*sh2  = 2

sh2 = sh1之后。两个sh1 ->int(1) <- sh2

int(2)会发生什么? 它已被销毁,因为sh2现在指向int(1)

因此,我们有

sh1.use_count == sh2.use_count
*sh1 == *sh2

* sh1和* sh2有1