首页
题库
公司真题
专项练习
面试题库
在线编程
面试
面试经验
AI 模拟面试
简历
求职
学习
基础学习课
实战项目课
求职辅导课
专栏&文章
竞赛
搜索
我要招人
发布职位
发布职位、邀约牛人
更多企业解决方案
AI面试、笔试、校招、雇品
HR免费试用AI面试
最新面试提效必备
登录
/
注册
土拨猫
武汉理工大学 C++
发布于湖北
关注
已关注
取消关注
@牛啊牛の:
智能指针
C++智能指针:防止内存泄漏,动态管理内存,分配-自动释放内存》》unique_ptr, shared_ptr, weak_ptr;属于封装类。 unique_ptr:unique_ptr实现独占式拥有或严格拥有概念,保证同一时间内只有一个智能指针可以指向该对象。它对于避免资源泄露,例如,以new创建对象后因为发生异常而忘记调用delete时的情形特别有用。 实现原理:将拷贝构造函数和赋值拷贝构造函数申明为private或delete。不允许拷贝构造函数和赋值操作符,但是支持移动构造函数,通过std:move把一个对象指针变成右值之后可以移动给另一个unique_ptr shared_ptr:shared_ptr实现共享式拥有概念。多个智能指针可以指向相同对象,该对象和其相关资源会在“最后一个引用被销毁”时候释放。从名字share就可以看出了资源可以被多个指针共享,它使用计数机制来表明资源被几个指针共享。可以通过成员函数use_count()来查看资源的所有者个数。除了可以通过new来构造,还可以通过传入auto_ptr, unique_ptr,weak_ptr来构造。当我们调用release()时,当前指针会释放资源所有权,计数减一。当计数等于0时,资源会被释放。 shared_ptr 是为了解决 auto_ptr 在对象所有权上的局限性(auto_ptr 是独占的), 在使用引用计数的机制上提供了可以共享所有权的智能指针。 use_count 返回引用计数的个数 ; unique 返回是否是独占所有权( use_count 为 1) ; swap 交换两个 shared_ptr 对象(即交换所拥有的对象) ; reset 放弃内部对象的所有权或拥有对象的变更, 会引起原有对象的引用计数的减少 ; get 返回内部对象(指针), 由于已经重载了()方法, 因此和直接使用对象是一样的.如 shared_ptr sp(new int(1)); sp 与 sp.get()是等价的 ; 初始化:因为带有参数的 shared_ptr 构造函数是 explicit 类型的,所以不能像这样std::shared_ptr<int> p1 = new int();隐式调用它构造函数。创建新的shared_ptr对象的最佳方法是使用std :: make_shared: std::shared_ptr<int> p1 = std::make_shared<int>(); SharedPtr<string> pstr(new string("abc")); std::make_shared 一次性为int对象和用于引用计数的数据都分配了内存,而new操作符只是为int分配了内存。 -------共享所有权如何在参考计数的帮助下工作的? 1、当新的 shared_ptr 对象与指针关联时,则在其构造函数中,将与此指针关联的引用计数增加1。 2、当任何 shared_ptr 对象超出作用域时,则在其析构函数中,它将关联指针的引用计数减1。如果引用计数变为0,则表示没有其他 shared_ptr 对象与此内存关联,在这种情况下,它使用delete函数删除该内存。 ----------创建 shared_ptr 时注意事项:不要使用同一个原始指针构造 shared_ptr;创建多个 shared_ptr 的正常方法是使用一个已存在的shared_ptr 进行创建,而不是使用同一个原始指针进行创建。 int *num = new int(23); std::shared_ptr<int> p1(num); std::shared_ptr<int> p2(p1); // 正确使用方法 std::shared_ptr<int> p3(num); // 不推荐 std::cout << "p1 Reference = " << p1.use_count() << std::endl; // 输出 2 std::cout << "p2 Reference = " << p2.use_count() << std::endl; // 输出 2 std::cout << "p3 Reference = " << p3.use_count() << std::endl; // 输出 1 假如使用原始指针num创建了p1,又同样方法创建了p3,当p1超出作用域时会调用delete释放num内存,此时num成了悬空指针,当p3超出作用域再次delete的时候就可能会出错。 weak_ptr:weak_ptr 是一种不控制对象生命周期的智能指针, 它指向一个 shared_ptr 管理的对象。进行该对象的内存管理的是那个强引用的 shared_ptr。weak_ptr只是提供了对管理对象的一个访问手段。weak_ptr 设计的目的是为配合 shared_ptr 而引入的一种智能指针来协助 shared_ptr 工作,它只可以从一个 shared_ptr 或另一个 weak_ptr 对象构造, 它的构造和析构不会引起引用记数的增加或减少。weak_ptr是用来解决shared_ptr相互引用时的死锁问题,如果说两个shared_ptr相互引用,那么这两个指针的引用计数永远不可能下降为0,资源永远不会释放。它是对对象的一种弱引用,不会增加对象的引用计数,和shared_ptr之间可以相互转化,shared_ptr可以直接赋值给它,它可以通过调用lock函数来获得shared_ptr。 class B;class A{public: shared_ptr<B> pb_; ~A(){ cout<<"A delete\n";}};class B{public: shared_ptr<A> pa_; ~B(){ cout<<"B delete\n";}};void fun(){ shared_ptr<B> pb(new B()); shared_ptr<A> pa(new A()); pb->pa_ = pa; pa->pb_ = pb; cout<<pb.use_count()<<endl; cout<<pa.use_count()<<endl;}int main(){ fun(); return 0;} 可以看到fun函数中pa ,pb之间互相引用,两个资源的引用计数为2,当要跳出函数时,智能指针pa,pb析构时两个资源引用计数会减一,但是两者引用计数还是为1,导致跳出函数时资源没有被释放(A B的析构函数没有被调用),如果把其中一个改为weak_ptr就可以了,我们把类A里面的shared_ptr pb_; 改为weak_ptr pb; 运行结果如下,这样的话,资源B的引用开始就只有1,当pb析构时,B的计数变为0,B得到释放,B释放的同时也会使A的计数减一,同时pa析构时使A的计数减一,那么A的计数为0,A得到释放。 注意:我们不能通过weak_ptr直接访问对象的方法,比如B对象中有一个方法print(),我们不能这样访问,pa->pb->print(); 英文pb是一个weak_ptr,应该先把它转化为shared_ptr,如:shared_ptr p = pa->pb_.lock(); p->print(); ----------1.5.6 weak_ptr 能不能知道对象计数为 0,为什么?参考回答: 不能。 weak_ptr是一种不控制对象生命周期的智能指针,它指向一个shared_ptr管理的对象。进行该对象管理的是那个引用的shared_ptr。weak_ptr只是提供了对管理 对象的一个访问手段。weak_ptr设计的目的只是为了配合shared_ptr而引入的一种智能指针,配合shared_ptr工作,它只可以从一个shared_ptr或者另一个weak_ptr对象构造,它的构造和析构不会引起计数的增加或减少。 --------1.5.7 weak_ptr 如何解决 shared_ptr 的循环引用问题? 参考回答: 为了解决循环引用导致的内存泄漏,引入了弱指针weak_ptr,weak_ptr的构造函数不会修改引用计数的值,从而不会对对象的内存进行管理,其类似一个普通指针,但是不会指向引用计数的共享内存,但是可以检测到所管理的对象是否已经被释放,从而避免非法访问。 ------------线程安全性 多线程环境下,调用不同shared_ptr实例的成员函数是不需要额外的同步手段的,即使这些shared_ptr拥有的是同样的对象。但是如果多线程访问(有写操作)同一个shared_ptr,则需要同步,否则就会有race condition 发生。也可以使用 shared_ptr overloads of atomic functions来防止race condition的发生。多个线程同时读同一个shared_ptr对象是线程安全的,但是如果是多个线程对同一个shared_ptr对象进行读和写,则需要加锁。 多线程读写shared_ptr所指向的同一个对象,不管是相同的shared_ptr对象,还是不同的shared_ptr对象,也需要加锁保护。例子如下: shared_ptr<long> global_instance = make_shared<long>(0);std::mutex g_i_mutex; void thread_fcn(){ //std::lock_guard<std::mutex> lock(g_i_mutex); //shared_ptr<long> local = global_instance; for(int i = 0; i < 100000000; i++) { *global_instance = *global_instance + 1; //*local = *local + 1; }} int main(int argc, char** argv){ thread thread1(thread_fcn); thread thread2(thread_fcn); thread1.join(); thread2.join(); cout << "*global_instance is " << *global_instance << endl; return 0;} 在线程函数thread_fcn的for循环中,2个线程同时对global_instance进行加1的操作。这就是典型的非线程安全的场景,最后的结果是未定的,运行结果如下: *global_instance is 197240539 如果使用的是每个线程的局部shared_ptr对象local,因为这些local指向相同的对象,因此结果也是未定的,运行结果如下: *global_instance is 160285803 因此,这种情况下必须加锁,将thread_fcn中的第一行代码的注释去掉之后,不管是使用global_instance,还是使用local,得到的结果都是: *global_instance is 200000000。 [考得全会][蒙的全对][面试必过][心想事成][成功上岸][offer+1][内推成功]
点赞 2
评论 3
全部评论
推荐
最新
楼层
暂无评论,快来抢首评~
相关推荐
2025-12-28 12:06
复旦大学 Java
关于校招面试,为啥面试官总是一副...
最近刷牛客看好多牛友吐槽面试官态度不好,高高在上,或者针对于某一家公司还做了个面试官排名。这个还是分人,绝大多数公司都面试官还是比较友好的。其实面试对于面试官来说只是工作的一部分,我们很多时候都是拿出工作写代码的时间来面试,相信大家面试的时候也看到面试官一边听你说一边在打字,要么就是在对需求要么就是在摸鱼,当然我感觉还是对需求的概率大哈哈。马上快到春招了,可能也有些小伙伴打算毁约准备春招,或者考研下岸冲刺春招,不管你是什么情况,都可以看看这个突击版学习路线https://www.nowcoder.com/users/664521299最后,不管你拿到什么Offer,适合自己就是最好的,希望各位...
找工作,行业重要还是岗位...
点赞
评论
收藏
分享
2025-12-29 12:01
门头沟学院 Java
求支招
本人现在的情况:我的第一份实习,也是现在在干的实习,是在懂车帝。十一月中旬入职的,中途请了差不多半个月工作日的假回学校考试(base和学校位置差太远,因为当时准备的晚,十月多才投递,广东这边真的不太好找),然后算了一下减去剩余的假期,到二月底,其实也就是两个月多点(如果加上请假那些天数勉强能凑个三月)。但是现在的情况是听说暑期实习基本3月就要开始投递了,有没有有经验的uu指导下现在应该做什么?我是打算再做一个ai agent的项目,然后偷点实习那边的东西,重新回顾一下八股和算法。另外,因为在这边干的是go,但我还是打算继续投java,要不要准备一些go的面试问题呢?感觉时间特别的赶,因为算了一...
点赞
评论
收藏
分享
2025-12-17 12:08
门头沟学院 产品经理
到底啥样的实习才算没白干?这几点说透了
1.大厂 title 加持🤩大公司的名头往简历上一搁,直接就加分!毕竟竞争这么卷,你能进得去,本身就证明简历没啥毛病。关键是得把工作内容挖深了,掰开揉碎了写进简历里,别浪费这个好背景。2.靠谱带教 + 合拍同事 + 舒服氛围👥就算每天干的都是打杂跑腿的活儿,只要这三样到位,这实习就值了!实习做琐事太正常了,但你可以逮着机会就请教领导同事,盯着他们咋干活、咋思考的,这些都是实打实的收获。对咱来说,能学到东西的实习,就是好实习!3.能上手真活儿,攒真本事💪要是不用天天打杂,能独立接触项目,甚至扛下一小块儿具体工作,那可就赚大了!既能提升实打实的工作能力,又能把业务流程摸得门儿清,这种实习含金量直接拉满。说到底,实习有没有用,还是得看自己的感受。要是干得憋屈、内耗严重,那果断跑路别犹豫!要么能给简历添彩,要么能让人干得开心有情绪价值,这样的实习才算没白忙活一场。
牛客85811352...:
1希音不知道算不算大厂 2完全符合,过得很舒服, 3确实只有杂活
领导找我续签到明年3、4月我要继续吗
。主要是边实习边秋招这段时间还是有点累
什么是优秀的实习经历
点赞
评论
收藏
分享
2025-12-09 16:33
已编辑
字节跳动_后端开发(实习员工)
第一个实习offer
鼠鼠我呀,究竟是怎样的结果,才配得上这一路的颠沛流离啊啊啊,原来是字节呀。从此化身节孝子,我的心只为你跳动
在秋招的河老师很爱吃:
我怎么刷了一天全是字节offer
实习必须要去大厂吗?
点赞
评论
收藏
分享
2025-12-29 16:45
莉莉丝游戏_2026届校招HRBP(准入职员工)
众安保险内推,众安保险内推码
众安保险产品运营1自我介绍2你偏向于产品运营还是产品经理3你能说说这两者的区别吗4 你认为两者分别有什么特质5 你认为自己具备什么特质6 你说一个你的缺点7你现在做的措施有帮助你改正缺点吗 你还有采取什么其他的措施吗8 你喜欢什么样的领导和团队氛围9 讲一个你实习内容10 你们部门架构是什么,你的leader主要负责什么?11说一个跨部门交流的经历 有没有遇到什么困难12 你为什么想投众安的产品运营呢?和你专业经历不太相符13 你为什么不留在现在实习的公司14 可以提前实习吗 目前投递了哪些公司15 你家哪里的 性格?星座?16 你如何看待加班呢众安保险26届校招启动啦【关于众安】众安保险是中...
点赞
评论
收藏
分享
评论
点赞成功,聊一聊 >
点赞
收藏
分享
评论
提到的真题
返回内容
全站热榜
更多
1
...
都 2026 年了,还在神话 AI Agent开发吗?
728
2
...
为什么你的实习是“无效实习”?又该如何做
633
3
...
最后一天,你的2025牛客年度报告即将封存!
563
4
...
简历求锐评,211硕士找实习
494
5
...
我的秋招回忆录:从惨败到硕果的成长之路
452
6
...
2025找工年终总结
395
7
...
字节实习生涨薪保真?
325
8
...
双非终于上岸了!!!!
293
9
...
Goodnight World!文科转码兜兜转转的那些年……
265
10
...
实习很多时候得靠自己
236
创作者周榜
更多
正在热议
更多
#
对2025年忏悔
#
9261次浏览
171人参与
#
机械/制造每日一题
#
82008次浏览
1428人参与
#
一人说一家双休的公司
#
13235次浏览
143人参与
#
机械求职避坑tips
#
82550次浏览
537人参与
#
实习没人带,苟住还是跑路?
#
18393次浏览
337人参与
#
非技术2023笔面经
#
316768次浏览
2684人参与
#
工作中,努力重要还是选择重要?
#
248302次浏览
2412人参与
#
如果秋招能重来,我会____
#
79529次浏览
471人参与
#
面试紧张时你会有什么表现?
#
21093次浏览
154人参与
#
应届生,你找到工作了吗
#
97460次浏览
595人参与
#
每个月的工资都是怎么分配的?
#
81664次浏览
665人参与
#
春招前还要继续实习吗?
#
11816次浏览
132人参与
#
虾皮求职进展汇总
#
362544次浏览
2767人参与
#
影石Insta360求职进展汇总
#
169305次浏览
1345人参与
#
你面试被问到过哪些不会的问题?
#
107247次浏览
1879人参与
#
秋招被确诊为……
#
280356次浏览
1589人参与
#
AI时代,哪些岗位最容易被淘汰
#
25886次浏览
222人参与
#
滴滴求职进展汇总
#
291518次浏览
2405人参与
#
工作后,谈恋爱还和学生时代一样吗?
#
46816次浏览
389人参与
#
2025秋招体验点评
#
86707次浏览
724人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务