【问题标题】:Can I have non owning shared pointers?我可以有非拥有的共享指针吗?
【发布时间】:2014-11-30 17:31:10
【问题描述】:

简介

问题源于对条件接口的需求。可能是因为我陷入了 XY 问题,但是(底线)我最终需要一个共享指针,它可以(基于运行时选择)管理或不管理(拥有或不拥有)资源。

工作至今

以下是关于非拥有共享指针

的一些想法
  1. 使用placement new,例如:

    struct MyStruct {}; 
    MyStruct ms1; 
    std::shared_ptr<MyStruct> sp(new(&ms1) MyStruct); 
    
  2. 使用虚拟删除器

    std::shared_ptr<MyStruct> spn(new MyStruct, [](MyStruct*){}); 
    

问题

  • 是否有标准的建议方式?
  • 是否有“不要这样做”的规则?
  • 至少有更好的方法吗?

注意事项

我的类布局(将使用非拥有共享指针)如下所示:

template<typename T>
struct blah
{
    shared_ptr<T> _m;
};

现在,_m 成员可能拥有也可能不拥有基于运行时选择的资源。我不使用weak_ptr 的原因是因为_m 实际上可能是一个拥有指针。

【问题讨论】:

  • 为什么不直接使用weak_ptr,这是它的设计目的还是我遗漏了什么?
  • 使用std::weak_ptr,然后可以提取shared_ptr作为局部变量(通过lock())供资源使用。
  • @EdChum 智能指针将成为类成员。我试图避免使用两个成员(一个weak 和一个shared 指针)加上一个标志来知道哪个是有效的。有没有办法总是只有 一个 成员?
  • @Niall 不是一段有效/工作的代码,只是一个编译片段来推测使用placement new 来拥有非拥有智能指针的可能性。该问题特别询问它是否有效,是否有有效的方法来做到这一点。
  • @NikosAthanasiou。如果两个成员都属于同一个类(对象),我看不出有两个成员的理由。拥有指针(因此指向父对象)拥有它,此时不需要额外的非拥有成员。

标签: c++ c++11 stl smart-pointers c++14


【解决方案1】:

位置 new 显然是 UB,因为它会在您的 sn-p 中尝试删除堆栈上的某些内容。空的删除器版本可以工作,但会分配一个引用计数块。

诀窍是使用shared_ptr 的疯狂(ok,aliasing)构造函数:

template< class Y > 
shared_ptr( const shared_ptr<Y>& r, T *ptr );

构造一个shared_ptr 拥有r 拥有的东西,但指向ptr 指向的东西,即:

std::shared_ptr<MyStruct> sp(std::shared_ptr<MyStruct>(), p);

这是由标准保证noexcept,并且不会分配任何东西。该标准甚至有一个注释说

[ 注意:这个构造函数允许创建一个空的shared_ptr 具有非空存储指针的实例。 —尾注 ]

【讨论】:

    【解决方案2】:

    new 位置会在销毁时为您提供未定义的行为(并且可能会导致崩溃) - 它会立即调用 delete 处理不是用 new 创建的东西。

    我会选择无操作删除器。该设计可能看起来很奇怪,但如果您需要这样的行为(并记录足够的内容),它会起作用。我曾经在我的一个项目中使用过类似的东西,但后来我不再需要它了。

    【讨论】:

    • 我想摆脱对它的需求是一个大赌注。
    • 绝对是无操作删除器;这就是 boost 具有 boost::null_deleter 的原因,它曾一度隐藏在序列化代码中,但现在位于核心中。当您需要诉诸于此时,几乎总是很不幸,但是如果您无法更改 API,则无法....(编辑)如果您所做的只是尝试拥有一个可能不拥有的指针,shared_ptr 是矫枉过正;滚动你自己的便利类,或者使用 unique_ptr 和一个删除器,它围绕一个布尔值来告诉它是否需要释放。如果在拥有的情况下需要共享所有权,shared_ptr 就可以了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多