在不绕过共享语义的情况下通过引用传输向量<shared_ptr<T>>

Transferring a vector<shared_ptr<T>> by reference without bypassing shared semantics

我有一个 class 其中包含一个 vector<shared_ptr<T>>:

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 超出范围,最后一行是否有效?

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

在此示例中,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();

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

是的,它是有效的。 您 class 按值保存向量,因此在您的 setter

_item = item

将复制整个向量