Подтвердить что ты не робот

Должен ли я использовать shared_ptr или unique_ptr?

У меня вопрос о std::unique_ptr и std::shared_ptr. Я знаю, что есть много вопросов о том, когда использовать какой, но я все еще не уверен, правильно ли я это понимаю. Я где-то читал, что выбор по умолчанию для интеллектуального указателя должен быть std::unique_ptr, но, насколько я понимаю, для моих нужд я должен использовать std::shared_ptr. Например, у меня есть:

class B;
class A
{
private:
   B* b;
public:
   B* getB();
};

A::getB()
{
   return b;
}

Итак, в основном класс A владеет указателем на объект типа B и там есть метод, который возвращает этот указатель. Если я создаю getter, я предполагаю, что некоторый другой класс может получить доступ к этому указателю, и поэтому он должен быть shared_ptr вместо unique_ptr. Я прав, или я еще не понял?

4b9b3361

Ответ 1

Короткий ответ: зависит.

Это зависит от того, может ли храниться/использоваться указатель, возвращаемый getB, когда владелец A вышел из сферы действия. Разница в том, что вы не владеете не тем количеством указателей, которое у вас есть.

  • Если A все еще существует, когда вы используете результат getB, вы можете сохранить unique_ptr и вернуть простой указатель (или ссылку, если getB никогда не сможет вернуть nullptr). Это выражает "A владеет B, и никто другой не делает".
  • Если A может выйти из области видимости, пока вы используете/удерживаете результат getB, но B должен выйти из области действия вместе с (или вскоре после) A, сохранить shared_ptr и вернуть weak_ptr.
  • Если возможно, что многие объекты, включая вызывающих абонентов getB, могут удержаться на B и нет четкого одиночного владельца, сохранить и вернуть shared_ptr s.

Ответ 2

Предположим для примера, что действительно нужен указатель, и просто B b; не разрезает его (возможно, B является, например, полиморфным).

Сценарий alpha

Итак, A является владельцем B.

private:
   std::unique_ptr<B> b;

И getB дает представление об этом.

public:
   B& getB();


B& A::getB()
{
   return *b;
}

Сценарий бета

A является одним из владельцев B.

private:
   std::shared_ptr<B> b;

И А может дать право владеть этим B другим.

public:
   std::shared_ptr<B> getB();


std::shared_ptr<B> A::getB()
{
   return b;
}

Ответ 3

Вы возвращаете пустой указатель, а не shared_ptr, поэтому использование общего указателя ничего не решит. Верните a shared_ptr или используйте unique_ptr. Постарайтесь подумать о том, как можно реализовать shared_ptr, и я считаю, что это должно сделать мою мысль ясной.

Ответ 4

Я думаю, что ты прав. Если бы вы указали только указатель B как частный член в A, я бы использовал std::unqiue_ptr.

Ответ 5

В вопросе не хватает информации.

Интеллектуальные указатели захватывают и реализуют семантику владения. Если объекту A принадлежит объект B, поэтому уничтожение A должно уничтожить B, а затем использовать unique_ptr. Но unique_ptr здесь не делает хорошего типа возврата. Это будет только член, и вы все равно вернете пустой указатель.

Если получение B означает, что клиент может продолжать использовать B неопределенно, используйте shared_ptr, потому что это будет совместное владение.