我有一个问题,请通过以下简单的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
对象中的变量。
答案 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的工作原理。