【问题标题】:Transferring a vector<shared_ptr<T>> by reference without bypassing shared semantics通过引用传输 vector<shared_ptr<T>> 而不绕过共享语义
【发布时间】:2019-11-11 05:13:02
【问题描述】:

我有一个包含vector&lt;shared_ptr&lt;T&gt;&gt;的类:

using SharedItems = std::vector<std::shared_ptr<Item>>;

class LargeLift
{
public:
    SharedItems& getItems()
    {
        return _items;
    }

    void setSharedItems(SharedItems& items)
    {
        _items = items;
    }

private:
    SharedItems _items;
};

然后我执行以下操作:

LargeLift b;
{
    LargeLift a;
    // Gets populated

    SharedItems& items = a.getItems();
    b.setSharedItems(items);
}

// Variable a is now out of scope

SharedItems& items2 = b.getItems();

鉴于a 已超出范围,最后一行是否有效?

【问题讨论】:

  • @Yksisarvinen 所以在上面的代码中,最后一行是不安全的,因为 a 已经超出范围。所以我应该让 getter() 按值返回?
  • a 没有超出上述示例的范围
  • @Eric 我说它有,以帮助我的问题。

标签: c++ c++11 shared-ptr smart-pointers


【解决方案1】:

代码将引用传递给setSharedItems,但SharedItems _items; 不是引用,因此_items = items;items 复制到_itemsa._itemsb._items 不同,所以ba 消失后会很好。由于b 复制了所有shared_ptrs,所以引用计数没有达到零,所有指针仍然是好的。

【讨论】:

    【解决方案2】:

    正如所写,您的代码是安全的 - 没有超出范围。

    在这个例子中,a 确实超出了范围,但事情仍然是安全的:

    LargeLift b;
    {
        LargeLift a;
        // Gets populated
    
        SharedItems& items = a.getItems();
    
        //give b its own copy
        b.setSharedItems(items);
    }
    
    // safe, because b owns its own copy
    SharedItems& items2 = b.getItems();
    

    在这个例子中,它们是不安全的:

    SharedItems* p_items;
    
    LargeLift b;
    {
        LargeLift a;
        // Gets populated
    
        items = &a.getItems();
    }
    
    // unsafe, items is already dangling
    b.setSharedItems(*p_items);
    
    SharedItems& items2 = b.getItems();
    

    【讨论】:

      【解决方案3】:

      是的,它是有效的。 你的类按值保存向量,所以在你的设置器中

      _item = item
      

      将复制整个向量

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-18
        • 2020-02-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多