Передача вектора <shared_ptr <T>> по ссылке без обхода общей семантики - PullRequest
3 голосов
/ 29 июня 2019

У меня есть класс, который содержит 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 вышел за рамки?

Ответы [ 3 ]

5 голосов
/ 29 июня 2019

Код передает ссылку в setSharedItems, но SharedItems _items; НЕ является ссылкой, поэтому _items = items; копирует items в _items. a._items отличается от b._items, поэтому b будет хорошо после того, как a исчезнет. Поскольку b сделал копии всех shared_ptr s, счетчики ссылок не достигли нуля, и все указатели все равно будут хорошими.

3 голосов
/ 29 июня 2019

Как написано, ваш код безопасен - ничего не вышло из области видимости.

В этом примере 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();
1 голос
/ 29 июня 2019

Да, это действительно.Ваш класс содержит вектор по значению, поэтому в вашем установщике

_item = item

будет скопирован весь вектор

...