Std::vector ссылок
У меня такая проблема: у меня есть класс Foo
, и если есть некоторые объекты этого класса,
Foo a();
Мне нужно поставить этот объект на два разных вектора:
std::vector<Foo> vA, vB;
и если a
изменяется в vA
, его следует изменить в vB
, векторы vA
и vB
могут быть разными, но они могут иметь одинаковые объекты. Я знаю, что это возможно с Boost, но я не могу использовать Boost.
Ответы
Ответ 1
Есть несколько возможностей:
-
Сохраните вектор указателей (используйте, если ваши векторы разделяют право собственности на указатели):
std::vector<std::shared_ptr<Foo>> vA, vB;
-
Храните вектор обернутых ссылок (используйте, если векторы не разделяют право собственности на указатели, и вы знаете, что ссылка на объект действительна за время жизни векторов):
std::vector<std::reference_wrapper<Foo>> vA, vB;
-
Сохраните вектор сырых указателей (используйте, если ваши векторы не разделяют права владения указателями и/или указатели, хранящиеся, могут меняться в зависимости от других факторов):
std::vector<Foo*> vA, vB;
Это обычное явление для наблюдения, отслеживания распределения и т.д. Применяются обычные предостережения для необработанных указателей: не используйте указатели для доступа к объектам по окончании их срока службы.
-
Храните вектор std::unique_ptr
, который обертывает объекты (используйте, если ваши векторы хотят передать владение указателями, в этом случае время жизни ссылочных объектов определяется правилами класса std::unique_ptr
).:
std::vector<std::unique_ptr<Foo>> vA, vB;
Ответ 2
Вам нужен вектор ссылок. И поскольку вы указываете, что вам нужно использовать std::vector, то правильная вещь, которую нужно сделать, это обернуть ваши объекты в std::reference_wrapper
. Эта страница из справки С++ должна объяснить это красиво:
vector<reference_wrapper<Foo>> vA, vB;
vA.push_back(a);
vB.push_back(a); // puts 'a' into both vectors
// make changes to 'a'
// use .get() to get the referenced object in the elements of your vector
// vA[0].get() == vB[0].get()
Ответ 3
Вместо сохранения объекта Foo в качестве указателя на объект Foo, например
std::vector<Foo *> vA, vB;
и аккуратно управлять распределениями и деаллокациями, чтобы избежать утечки памяти (Выделение, но не освобождение, когда это делается). Если вы выделяете один объект Foo и сохраняете указатель как в vA, так и в vB, вы сохраняете по существу один и тот же объект в обоих указателях.
В противном случае вы можете использовать интеллектуальный указатель (лучше)
обратитесь:
Что такое умный указатель и когда его следует использовать?