#c #smart-pointers #unique-ptr
Вопрос:
Я пытаюсь перейти от голых указателей к умным указателям. Но я не совсем уверен, как сохранить currentBar (который также будет находиться в myBars), используя уникальные указатели
Class Foo
{
public:
Bar* getCurrentBar();
//!! other stuff not important
private:
Bar* currentBar;
std::vector<Bar *> myBars;
};
Я не считаю, что мне следует использовать общий указатель, так как единственное, что имеет право собственности на объект,-это Foo,
Для
Class Foo
{
public:
std::unique_ptr<Bar> getCurrentBar(); //? returns currentBar, whatever currentBar is;
private:
std::unique_ptr<Bar> currentBar; //? What do I do here?
std::vector<std::unique_ptr<Bar>> myBars;
};
Вышесказанное не работает, но я хотел бы сделать что-то подобное вышесказанному. Как мне это сделать? (Я бы предпочел не использовать общий указатель).
Комментарии:
1. Если
Foo
предполагается , что указатель принадлежит даже после того, как кто-то позвонилgetCurrentBar()
, не возвращайте aunique_ptr
. Сделайте это:Bar* getCurrentBar() { return currentBar.get(); }
.- Кроме того, вы не можете иметь один и тот же указательunique_ptr
, завернутый в обаcurrentBar
иmyBars
. Кстати, вам вообще нужно использовать указатели? Почему нетstd::vector<Bar> myBars;
?2. не тема вопроса, но как только вы возвратили указатель на не-const или ссылку на не-const из общедоступного источника, вам не нужно делать участника закрытым. При вызове
getCurrentBar
вызывающий абонент имеет прямой доступ к участнику, вся защита доступа обходится
Ответ №1:
Нет ничего плохого в том, чтобы не владеть необработанными указателями. Используйте unique_ptr
в векторе для управления временем жизни, а затем используйте обычные указатели или ссылки для своего интерфейса. Это выглядело бы так
Class Foo
{
public:
Bar* getCurrentBar();
// or Baramp; getCurrentBar();
private:
Bar* currentBar;
std::vector<std::unique_ptr<Bar>> myBars;
};
Комментарии:
1. Примечание о том, почему
std::unique_ptr<Bar> getCurrentBar();
плохо: при оформленииstd::unique_ptr<Bar>
того, что возвращается, нынешний владелец будет лишен права собственности. Помните, что уникальное означает, что может быть только одно. Если вы пройдетеunique_ptr
, вы передадите права собственности, чтобы сохранить уникальность. Если у вас каким-то образом есть несколькоstd::unique_ptr
s, указывающих на один и тот же объект, вы нарушили правила и вам предстоит тяжелое время.