c++中引用和智能指针的简单问题

2021-02-04 17:20:51 +08:00
 ruokw
传入对象引用,例如 json-value ( A )。现在想把它包装成新对象( B{A})返回,但是底层指向同一个对象。而且 B 要支持无参构造。使用智能指针去包装 A 会出现超过域后过早释放空间的问题。想问下这种情况下有什么好的解决方法吗?
1505 次点击
所在节点    问与答
23 条回复
yianing
2021-02-04 17:39:39 +08:00
那在有参构造的时候传入智能指针的拷贝不就行了吗?
ruokw
2021-02-04 17:50:37 +08:00
@yianing 现在问题是 A 应该是在 B 之后才会被释放,但是 B 保存 A 的智能指针,在 B 死亡时会提前释放掉 A 。
yianing
2021-02-04 18:12:58 +08:00
@ruokw B 死亡时只会将 A 的引用数减一,并不会释放掉指针指向的内存吧,只有引用数变为 0 的时候才会真正释放内存
wutiantong
2021-02-04 18:19:10 +08:00
你没有描述清楚你的问题
ruokw
2021-02-04 18:31:55 +08:00
@wutiantong 补充了
ruokw
2021-02-04 18:32:02 +08:00
@yianing 补充了
wevsty
2021-02-04 18:51:30 +08:00
首先把传入的引用转换为智能指针是一种强烈不推荐的做法。
其次,shared_ptr 在超过生存周期的时候会自动对引用计数减 1,如果引用计数为 0 就会去 delete 管理的对象。如果不想 shared_ptr 指针去 delete 这个对象,要不然增加引用计数,要不然就延长 shared_ptr 的生存周期。
yianing
2021-02-04 19:03:34 +08:00
好家伙,都用智能指针了为什么还要去获取裸指针呢?
ruokw
2021-02-04 19:04:16 +08:00
@wevsty 这个能明白。现在的问题是实际上 B 被作为类型的集合,用来统一一类函数的返回类型,B{int string long A},如果 B 里面 A 用引用,就又意味着 B 不能无参构造了。 所以现在有啥好的方法? 还是说只能整个重新设计?
ruokw
2021-02-04 19:09:11 +08:00
@yianing 你是说 shared_ptr(&a)么? 至少我现在在 mxvc2011 里面对引用 a 构造智能指针要用&a 。这点也比较难理解,为啥引用还有指针?
yianing
2021-02-04 19:12:50 +08:00
@ruokw 智能指针创建的正确使用姿势是 std::make_shared,你这把传进来的实例引用取地址绝对有问题啊🌚🌚
imjamespond
2021-02-04 19:36:09 +08:00
可以用 weak ptr 啊。。。
ruokw
2021-02-04 19:38:42 +08:00
@yianing 这个也能明白,但是现在情况是 B 不仅包装包装 a 而是包装 a 的子对象比方说 a 是 json::Value ,b=shared_ptr(a["num"])。 这时候可能光 a 是智能指针都不够
ruokw
2021-02-04 19:39:56 +08:00
@imjamespond 用 weak 还是得先有 shared 哈,有 shared 就又回到最初的说的了
hazardous
2021-02-04 19:53:17 +08:00
使用 shared_ptr 第二个参数:自定义 deletor
hazardous
2021-02-04 20:02:23 +08:00
还有个问题是很难保证传入 A 的引用一定是 new 出来的对象,如果是个栈上对象那 shared_ptr 释放的时候就崩了。
ruokw
2021-02-04 20:08:01 +08:00
@hazardous 我把 deletor 设置成空,最原始的 a 在栈上,现在只是说用智能指针代替引用。在我现在这个场景应该够用了。谢谢你了哈😄
wutiantong
2021-02-04 20:40:01 +08:00
楼主这 c++纯属瞎写啊。。。

首先我们有 enable_shared_from_this ( https://en.cppreference.com/w/cpp/memory/enable_shared_from_this ),
其次我们有 aliasing constructor for shared_ptr ( https://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr #8 )
mainjzb
2021-02-04 20:55:30 +08:00
..你已经把生死权交给 b 了。
所以 b 死了,拉着 a 一起死很正常。
不想交给 b 就用普通指针。所以用智能指针的意义何在。
ruokw
2021-02-04 20:55:44 +08:00
@wutiantong 哈哈 新手上路嘛,我看看你说的哈

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/751319

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX