复杂设计中的Shared_ptr和逻辑指针所有权用例
shared_ptr and logical pointer ownership use-case in a complex design
我有一个对象A
,它包含一个共享资源(shared_ptr) r
, A
是r
的创建者/所有者,在构建对象时,对象"注册"其r
与另一个对象B。对象B在std::set
中持有对A
的r
的引用。对象A用作Boost::asio::处理程序。
当A
被销毁时,我需要从B
中注销r
,当A
拥有对r
的唯一访问权时,因为A
是r
的创建者,它负责销毁它。注意:当A被用作boost::asio处理程序时,它的副本被构造多次。在这里保持唯一访问意味着没有asio操作发生(因为如果它们是引用计数将> 2,因为复制了A
)。
目前r.use_count() == 2
可以测试唯一访问,因为当没有异步操作发生时,A和B都可以访问对象。然而,我不认为这个测试在逻辑上是合理的。
我想我应该把B的容器从std::set<boost::shared_ptr<r> >
改为std:set<boost::weak_ptr<r> >
,这样当没有异步操作发生时,r.unique()
在逻辑上是正确的。这是一个明智的使用weak_ptr
?
A
(in_process_invoker)的构造函数和析构函数以及寄存器(connect)和unregister(disconnect)事件在我的代码中如下所示:
in_process_invoker(BackEnd & b_in)
: client_data(new ClientData()),
b(b_in),
notification_object(new notification_object_())
{
b.connect(client_data);
}
~in_process_invoker()
{
if(client_data.unique())
{
b.disconect(client_data);
}
}
编辑
我更改了设计,使用原始指针,默认构造函数将调用者标记为主调用者,并将其副本标记为非主调用者。
如果您确定B
持有的引用在A
执行引用计数测试时仍然存在,那么为什么在B
中使用任何类型的智能指针,为什么不使用原始指针?如果你不知道B
仍然会保存一个引用,那么当前的== 2
测试不仅是不明智的,而且是不正确的。
我看到的weak_ptr
相对于原始指针的唯一优势是,如果您在将来更改内容,使A
不会与B
注销,因此引用可能会摆动,然后weak_ptr
变得有用来告诉B
发生了什么。这甚至可能不可能取决于B
如何使用r
:如果设计严重依赖于引用总是有效的事实,那么就没有必要放弃尝试来掩盖它不是的情况。
你可以在任何地方坚持使用shared_ptr
,但是,如果A
通过shared_ptr
对代理对象持有对r
的引用,而B
通过shared_ptr
直接持有对r
的引用。然后让代理对象负责从B
取消注册。这样,要销毁的A
的最后一个副本将销毁代理,代理将注销B
,然后销毁r
。不需要任何人检查use_count
。
一个类似的选项是B
持有一个原始指针,并让r
在其析构函数中取消对B
的注册。我不确定,使线程安全可能更难。
理想情况下,你应该使用"右"指针类型的所有权语义。如果B
共同拥有r
,那么它应该有一个shared_ptr
,这样r
就可以安全地超过A
。如果B
不拥有r
,那么如果r
在销毁之前可能不会从B
注销,则使用weak_ptr
(并确保B
在weak_ptr
过期时做正确的事情),或者如果B
有其他人的保证以确保指针的有效性,则使用原始指针。
混合使用智能指针和原始指针是不安全的。的使用智能指针的全部意义在于找到一种方法来管理对象的回收,以及raw指针破坏了这一点,因为没有办法知道非null的原始指针是否有效。
你使用弱指针的解决方案对我来说似乎很合理——它清楚地区分了拥有和不拥有参考文献我已广泛使用在这种方法中,对象A被1所拥有另一个对象B,它将它保存到一个长期的共享指针,同样的对象A也是从任意数量的其他对象C-Z中引用通过弱指针。参考我对一个相关问题的回答:shared_ptr: what's it used for
- 智能指针概念所有权和寿命
- 如何指示指针C++所有权
- 如何将所有权从一个共享指针向量转移到另一个向量?
- C++类指针和所有权
- 什么是资源或指针的所有权?
- 进入智能指针,如何处理代表所有权
- 将智能指针所有权转移到容器
- 将原始指针的所有权转移到unique_ptr
- 明智的指针所有权语义和平等
- EIGEN地图 - 它是否占数据指针的所有权
- 带有原子变量的指针所有权
- 如果指针已经被删除,指针容器怎么能拥有指针的所有权
- 是否使用unique_ptr作为所有权和原始指针
- 文件输入和指针所有权语义
- 指针所有权
- Objective-C ARC 指针所有权与C++
- 唯一的指针所有权
- 复杂设计中的Shared_ptr和逻辑指针所有权用例
- c++ 11智能指针所有权和类型转换
- 声明现有原始指针所有权的正确方法