Лучшие практики? Преобразование указателей в Unique_Ptrs

#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() , не возвращайте a unique_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, указывающих на один и тот же объект, вы нарушили правила и вам предстоит тяжелое время.