sharedPtr
创始人
2024-03-04 09:33:00

shared_ptr

在这里插入图片描述

1.以何种方式传递

通过下列方式将 shared_ptr 传递给其他函数:

按值传递 shared_ptr。 这将调用复制构造函数,增加引用计数,并使被调用方成为所有者。 此操作的开销很小,但此操作的开销可能很大,具体取决于要传递多少 shared_ptr 对象。 当调用方和被调用方之间的(隐式或显式)代码协定要求被调用方是所有者时,请使用此选项。

按引用或常量引用传递 shared_ptr。 在这种情况下,引用计数不会增加,并且只要调用方不超出范围,被调用方就可以访问指针。 或者,被调用方可以决定基于引用创建一个 shared_ptr,并成为一个共享所有者。 当调用方并不知道被调用方,或当您由于性能原因必须传递一个 shared_ptr 且希望避免复制操作时,请使用此选项。

传递基础指针或对基础对象的引用。 这使被调用方能够使用对象,但不会使其能够共享所有权或延长生存期。 如果被调用方通过原始指针创建一个 shared_ptr,则新的 shared_ptr 独立于原始的,并且不会控制基础资源。 当调用方和被调用方之间的协定明确指定调用方保留 shared_ptr 生存期的所有权时,请使用此选项。

在确定如何传递 shared_ptr 时,确定被调用方是否必须共享基础资源的所有权。 “所有者”是只要它需要就可以使基础资源一直有效的对象或函数。 如果调用方必须保证被调用方可以将指针的生命延长到其(函数)生存期以外,则请使用第一个选项。 如果您不关心被调用方是否延长生存期,则按引用传递并让被调用方复制或不复制它。

如果必须为帮助器函数提供对基础指针的访问权限,并且你知道帮助器函数将使用该指针并且将在调用函数返回前返回,则该函数不必共享基础指针的所有权。 它只需在调用方的 shared_ptr 的生存期内访问指针即可。 在这种情况下,按引用传递 shared_ptr 或传递原始指针或对基础对象的引用是安全的。 通过此方式传递将提供一个小的性能好处,并且还有助于您表达编程意图。

有时,例如,在一个 std::vector 中,您可能必须将每个 shared_ptr 传递给 lambda 表达式主体或命名函数对象。 如果 lambda 或函数没有存储指针,则将按引用传递 shared_ptr 以避免调用每个元素的复制构造函数

2. 裸指针

shared_ptr sp = new int(100);//不能用裸指针初始化sp
share_ptr sp3(new int(100));//合法int *x(new int(100));
shared_ptr sp1(x);
shared_ptr sp2(x);
//x为裸指针,不合法,且sp1 sp2虽然都指向x所指向的内存,但是二者是独立的,当sp1释放时,x会变成空悬指针,sp2也很危险了shared_ptr sp1(new int(10));shared_ptr sp2(sp1.get());//get返回的是裸指针,error
sp.reset(sp1.get());

3. 线程安全

(shared_ptr)的引用计数本身是安全且无锁的,但对象的读写则不是,因为 shared_ptr 有两个数据成员,读写操作不能原子化。根据文档(http://www.boost.org/doc/libs/release/libs/smart_ptr/shared_ptr.htm#ThreadSafety), shared_ptr 的线程安全级别和内建类型、标准库容器、std::string 一样,即:

• 一个 shared_ptr 对象实体可被多个线程同时读取(文档例1);

• 两个 shared_ptr 对象实体可以被两个线程同时写入(例2),“析构”算写操作;

• 如果要从多个线程读写同一个 shared_ptr 对象,那么需要加锁(例3~5)。

请注意,以上是 shared_ptr 对象本身的线程安全级别,不是它管理的对象的线程安全级别。

后文(p.18)则介绍如何高效地加锁解锁。本文则具体分析一下为什么“因为 shared_ptr 有两个数据成员,读写操作不能原子化”使得多线程读写同一个 shared_ptr 对象需要加锁。这个在我看来显而易见的结论似乎也有人抱有疑问,那将导致灾难性的后果,值得我写这篇文章。本文以 boost::shared_ptr 为例,与 std::shared_ptr 可能略有区别。

shared_ptr 的数据结构
shared_ptr 是引用计数型(reference counting)智能指针,几乎所有的实现都采用在堆(heap)上放个计数值(count)的办法(除此之外理论上还有用循环链表的办法,不过没有实例)。具体来说,shared_ptr 包含两个成员,一个是指向 Foo 的指针 ptr,另一个是 ref_count 指针(其类型不一定是原始指针,有可能是 class 类型,但不影响这里的讨论),指向堆上的 ref_count 对象。ref_count 对象有多个成员,具体的数据结构如图 1 所示,其中 deleter 和 allocator 是可选的。

unordered容器时,退化成链表

shared_ptr 作为 unordered_map 的 key
如果把 boost::shared_ptr 放到 unordered_set 中,或者用于 unordered_map 的 key,那么要小心 hash table 退化为链表。http://stackoverflow.com/questions/6404765/c-shared-ptr-as-unordered-sets-key/12122314#12122314

直到 Boost 1.47.0 发布之前,unordered_set 虽然可以编译通过,但是其 hash_value 是 shared_ptr 隐式转换为 bool 的结果。也就是说,如果不自定义hash函数,那么 unordered_{set/map} 会退化为链表。https://svn.boost.org/trac/boost/ticket/5216

Boost 1.51 在 boost/functional/hash/extensions.hpp 中增加了有关重载,现在只要包含这个头文件就能安全高效地使用 unordered_setstd::shared_ptr 了。

refhttps://blog.csdn.net/solstice/article/details/8547547

4 管理socket FILE

将打开的文件句柄交给shared_ptr管理,如果发生任何不当行为,shared_ptr会帮助我们自动释放资源,程序员也不用自己显式写出fclose。
如果文件不存在,那么shared_ptr管理的是空指针,这样会在fclose发生异常,为了避免,先打开后判断是否为空哈

shared_ptr fp(fopen("/test.txt","r"),fclose);

一个自定义类管理套接字资源,自定义一个合适的资源释放函数,更加高效!!

Socket* openSocket()
{//do something
}void closeSocket()
{//do something
}auto s= openSocket();
if (s != nullptr)
{shared_ptr p(s, closeSocket);
}
else
{return -1;
}

5. 性能

1. share_ptr的size是裸指针的两倍:指向到该资源的裸指针,指向到该资源的引用计数的裸指针
2. 引用计数的内存必须动态分配
3. 引用计数的递增和递减必须是原子操作

6. 数组与容器

1. share_ptr的size是裸指针的两倍:指向到该资源的裸指针,指向到该资源的引用计数的裸指针
2. 引用计数的内存必须动态分配
3. 引用计数的递增和递减必须是原子操作

6. 数组与容器

​ 没有所谓的share_ptr,以array vector string替代,但是unique_ptr有

相关内容

热门资讯

demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...