了解C ++ std :: shared_ptr

时间:2018-10-22 09:35:08

标签: c++ shared-ptr smart-pointers reference-counting

我有一个问题,请通过以下简单的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

sptr1sptr3对象如何知道引用计数在打印4时会增加。

据我所知,引用计数是每个shared_ptr对象中的变量。

2 个答案:

答案 0 :(得分:14)

  

据我所知,引用计数是每个shared_ptr对象中的变量。

否,引用计数存储在堆上的“控制块”中。每个export const PostsFilter = (props) => ( <Filter {...props}> <TextInput label='Post ID' source='id' alwaysOn /> <TextInput label='User ID' source='user_id' alwaysOn /> </Filter> ); 实例都指向同一个“控制块”并保持活动状态(直到所有实例以及与它们共享所有权的所有shared_ptr实例都消失了。)

答案 1 :(得分:0)

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](当strong为0且weak为非零时,将调用类型擦除的破坏器,但控制块仍保留)。

顺便说一句,当您致电make_shared时,会这样做:

[strong reference count]
[weak reference count]
[type-erased destroyer fptr]
[object data]

现在,指向对象的指针指向控制块末尾的[object data]。这样可以将分配数量减少到一个。

需要使用单独的数据和控制块指针,原因是具有以下特性:要派生的shared_ptr可以更改为基于based的shared_ptr;在许多情况下,这需要调整指针值。同样,共享ptr的别名构造函数使控制块和指向的对象完全不相关。

来自@Estinox的答案(不是答案),这里是Channel9 talk,说明共享ptr的工作原理。