了解 C++ std::shared_ptr
Understanding C++ std::shared_ptr
我有一个问题,请看下面这个简单的C++程序,
int main( )
{
shared_ptr<int> sptr1( new int );
shared_ptr<int> sptr2 = sptr1;
shared_ptr<int> sptr3;
shared_ptr<int> sptr4;
sptr3 = sptr2;
cout<<sptr1.use_count()<<endl;
cout<<sptr2.use_count()<<endl;
cout<<sptr3.use_count()<<endl;
sptr4 = sptr2;
cout<<sptr1.use_count()<<endl;
cout<<sptr2.use_count()<<endl;
cout<<sptr3.use_count()<<endl;
return 0;
}
输出:
3
3
3
4
4
4
sptr1
和 sptr3
对象如何知道引用计数在打印 4 时递增。
据我所知,引用计数是每个 shared_ptr
对象中的一个变量。
As far as i know reference count is a variable in each shared_ptr object.
不,引用计数存储在堆上的一个"control block"中。每个 shared_ptr
实例都指向同一个 "control block" 并保持它的活动状态(直到所有实例和所有与它们共享所有权的 weak_ptr
实例都死了)。
一个shared_ptr<T>
通常实现为两个指针。一个指向对象数据,一个指向如下所示的结构:
[strong reference count]
[weak reference count]
[type-erased destroyer fptr]
[type-erased destroyer data]
其中 [object ptr]
指向实际对象。
当您复制 shared_ptr
时,它会创建另一个指向上述数据(和实际对象)的指针并递增它的 [strong reference count]
部分。弱指针的行为类似,但增加了 [weak reference count]
(当强为 0 且弱为非零时 - 类型擦除的破坏者被调用但控制块仍然存在)。
顺便说一句,当您调用 make_shared
时,它会:
[strong reference count]
[weak reference count]
[type-erased destroyer fptr]
[object data]
对象指针现在指向控制块末尾的 [object data]
。这将分配数量减少到一个。
需要一个单独的数据和控制块指针,因为诸如 shared_ptr to derived 可以更改为 shared_ptr to base 这样的特性;在许多情况下需要调整指针值。同样,shared ptr的别名构造函数允许控制块和指向的对象完全无关。
摘自@Estinox 的答案——这不是答案,这里是关于共享 ptr 如何工作的Channel9 talk。
我有一个问题,请看下面这个简单的C++程序,
int main( )
{
shared_ptr<int> sptr1( new int );
shared_ptr<int> sptr2 = sptr1;
shared_ptr<int> sptr3;
shared_ptr<int> sptr4;
sptr3 = sptr2;
cout<<sptr1.use_count()<<endl;
cout<<sptr2.use_count()<<endl;
cout<<sptr3.use_count()<<endl;
sptr4 = sptr2;
cout<<sptr1.use_count()<<endl;
cout<<sptr2.use_count()<<endl;
cout<<sptr3.use_count()<<endl;
return 0;
}
输出:
3
3
3
4
4
4
sptr1
和 sptr3
对象如何知道引用计数在打印 4 时递增。
据我所知,引用计数是每个 shared_ptr
对象中的一个变量。
As far as i know reference count is a variable in each shared_ptr object.
不,引用计数存储在堆上的一个"control block"中。每个 shared_ptr
实例都指向同一个 "control block" 并保持它的活动状态(直到所有实例和所有与它们共享所有权的 weak_ptr
实例都死了)。
一个shared_ptr<T>
通常实现为两个指针。一个指向对象数据,一个指向如下所示的结构:
[strong reference count]
[weak reference count]
[type-erased destroyer fptr]
[type-erased destroyer data]
其中 [object ptr]
指向实际对象。
当您复制 shared_ptr
时,它会创建另一个指向上述数据(和实际对象)的指针并递增它的 [strong reference count]
部分。弱指针的行为类似,但增加了 [weak reference count]
(当强为 0 且弱为非零时 - 类型擦除的破坏者被调用但控制块仍然存在)。
顺便说一句,当您调用 make_shared
时,它会:
[strong reference count]
[weak reference count]
[type-erased destroyer fptr]
[object data]
对象指针现在指向控制块末尾的 [object data]
。这将分配数量减少到一个。
需要一个单独的数据和控制块指针,因为诸如 shared_ptr to derived 可以更改为 shared_ptr to base 这样的特性;在许多情况下需要调整指针值。同样,shared ptr的别名构造函数允许控制块和指向的对象完全无关。
摘自@Estinox 的答案——这不是答案,这里是关于共享 ptr 如何工作的Channel9 talk。