制作 shared_ptr 的副本时会发生什么?
What happens when a copy of shared_ptr is made?
我想了解当 shared_ptr
被分配给另一个时,shared_ptr
中托管对象的引用计数是如何受到影响的。
我在 C++ primer,第 5 版 中看到以下语句:
For example, the counter associated with a shared_ptr is incremented
when ... we use it as the right-hand operand of an assignment...
The counter is decremented when we assign a new value to the
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;
}
Output:
sh1 use count: 2
sh2 use count: 2
sh2
的use_count
怎么可能也是2?根据上面提到的文字,它不应该是 0 吗?我在这里遗漏了什么吗?
起初你有 sh1.use_count=1
和 sh2.use_count=1
。现在,当您使用 sh2=sh1
分配时,会发生以下情况:
sh2
计数器减一,因为sh2
(shared_ptr
)要取另一个指针
- 自
sh2.use_count=0
以来,其指针下的对象,即int(2)
被销毁。
- 现在您将
sh2
分配给了一个属于 sh1
的新对象,因此它的计数器增加了 1,所以:sh2.use_count=2
,当然还有 sh1.use_count=2
,因为两个shared_ptr
对象都指向同一个对象,也就是int(1)
.
原来我们有
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
我认为出现这种误解是因为您认为计数器与指向拥有对象的指针一起存储在 shared_ptr
实例中。然而实际上 shared_ptr
的实例仅包含指向内部存储对象的指针,该对象包含引用计数器和指向拥有对象的指针。因此,当您执行 sh2 = sh1;
分配时,您使 sh2
引用与 sh1
相同的内部存储对象,因此采用 sh1
和 sh2
报告的计数器值来自同一来源。
我想了解当 shared_ptr
被分配给另一个时,shared_ptr
中托管对象的引用计数是如何受到影响的。
我在 C++ primer,第 5 版 中看到以下语句:
For example, the counter associated with a shared_ptr is incremented when ... we use it as the right-hand operand of an assignment... The counter is decremented when we assign a new value to the 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;
}
Output:
sh1 use count: 2
sh2 use count: 2
sh2
的use_count
怎么可能也是2?根据上面提到的文字,它不应该是 0 吗?我在这里遗漏了什么吗?
起初你有 sh1.use_count=1
和 sh2.use_count=1
。现在,当您使用 sh2=sh1
分配时,会发生以下情况:
sh2
计数器减一,因为sh2
(shared_ptr
)要取另一个指针- 自
sh2.use_count=0
以来,其指针下的对象,即int(2)
被销毁。 - 现在您将
sh2
分配给了一个属于sh1
的新对象,因此它的计数器增加了 1,所以:sh2.use_count=2
,当然还有sh1.use_count=2
,因为两个shared_ptr
对象都指向同一个对象,也就是int(1)
.
原来我们有
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
我认为出现这种误解是因为您认为计数器与指向拥有对象的指针一起存储在 shared_ptr
实例中。然而实际上 shared_ptr
的实例仅包含指向内部存储对象的指针,该对象包含引用计数器和指向拥有对象的指针。因此,当您执行 sh2 = sh1;
分配时,您使 sh2
引用与 sh1
相同的内部存储对象,因此采用 sh1
和 sh2
报告的计数器值来自同一来源。