В чем разница между пустым и нулевым std :: shared_ptr в C ++?

Страница cplusplus.com shared_ptr вызывает различие между пустым std::shared_ptr и null shared_ptr . На странице cppreference.com явно не указано различие, но используется как «пустое», так и сравнение с nullptr в описании поведения std::shared_ptr .

Есть ли разница между пустым и null shared_ptr ? Есть ли какой-либо прецедент для таких указателей со смешанным поведением? Имеет ли смысл не пустой номер null shared_ptr ? Был бы когда-нибудь случай в обычном использовании (т. Е. Если бы вы явно не построили его), где вы могли бы получить пустой, но не нулевой shared_ptr ?

И любой из этих ответов изменится, если вы используете версию Boost вместо версии C ++ 11?

Это странный угол поведения shared_ptr . У этого есть конструктор, который позволяет вам сделать shared_ptr который владеет чем-то, и указывает на что-то еще:

 template< class Y > shared_ptr( const shared_ptr& r, T *ptr ); 

shared_ptr построенный с использованием этого конструктора, делится владением с r , но указывает на то, что указывает ptr (т. ptr get() или operator->() вернет ptr ). Это удобно для случаев, когда ptr указывает на подобъект (например, элемент данных) объекта, принадлежащего r .

Связанная с вами страница вызывает shared_ptr который не имеет ничего пустого , и shared_ptr который указывает на ничего (т. get() == nullptr ) null . ( Пустой используется в этом смысле по стандарту, null – нет.) Вы можете создать пустой, но не пустой shared_ptr , но это будет не очень полезно. Пустой, но не нулевой shared_ptr по сути, является не владеющим указателем, который может использоваться для выполнения некоторых странных вещей, таких как передача указателя на то, что выделено в стеке, функции, ожидающей shared_ptr (но я бы предложил перфорировать кого бы то ни было сначала поместите shared_ptr в API).

boost::shared_ptr также имеет этот конструктор , который они называют конструктором псевдонимов .

Есть ли разница между пустым и null shared_ptr?

Пустой shared_ptr не имеет контрольного блока, а его счет использования считается равным 0. Копия пустого shared_ptr – это еще один пустой shared_ptr . Они оба являются отдельными shared_ptr s, которые не имеют общего блока управления, потому что у него его нет. Пустой shared_ptr можно построить с помощью конструктора по умолчанию или с конструктором, который принимает nullptr .

shared_ptr null shared_ptr имеет блок управления, который можно использовать совместно с другими shared_ptr s. Копия непустого null shared_ptr является shared_ptr который имеет тот же блок управления, что и исходный shared_ptr поэтому счетчик использования не равен 0. Можно сказать, что все копии shared_ptr имеют один и тот же nullptr . shared_ptr null shared_ptr может быть построен с нулевым указателем типа объекта (не nullptr )

Вот пример:

 #include  #include  int main() { std::cout << "std::shared_ptr ptr1:" << std::endl; { std::shared_ptr ptr1; std::cout << "\tuse count before copying ptr: " << ptr1.use_count() << std::endl; std::shared_ptr ptr2 = ptr1; std::cout << "\tuse count after copying ptr: " << ptr1.use_count() << std::endl; std::cout << "\tptr1 is " << (ptr1 ? "not null" : "null") << std::endl; } std::cout << std::endl; std::cout << "std::shared_ptr ptr1(nullptr):" << std::endl; { std::shared_ptr ptr1(nullptr); std::cout << "\tuse count before copying ptr: " << ptr1.use_count() << std::endl; std::shared_ptr ptr2 = ptr1; std::cout << "\tuse count after copying ptr: " << ptr1.use_count() << std::endl; std::cout << "\tptr1 is " << (ptr1 ? "not null" : "null") << std::endl; } std::cout << std::endl; std::cout << "std::shared_ptr ptr1(static_cast(nullptr))" << std::endl; { std::shared_ptr ptr1(static_cast(nullptr)); std::cout << "\tuse count before copying ptr: " << ptr1.use_count() << std::endl; std::shared_ptr ptr2 = ptr1; std::cout << "\tuse count after copying ptr: " << ptr1.use_count() << std::endl; std::cout << "\tptr1 is " << (ptr1 ? "not null" : "null") << std::endl; } std::cout << std::endl; return 0; } 

Он выводит:

 std::shared_ptr ptr1: use count before copying ptr: 0 use count after copying ptr: 0 ptr1 is null std::shared_ptr ptr1(nullptr): use count before copying ptr: 0 use count after copying ptr: 0 ptr1 is null std::shared_ptr ptr1(static_cast(nullptr)) use count before copying ptr: 1 use count after copying ptr: 2 ptr1 is null 

http://coliru.stacked-crooked.com/a/54f59730905ed2ff

  • std :: shared_ptr безопасность streamов
  • std :: shared_ptr этого
  • Когда используется std :: weak_ptr?
  • Пример использования shared_ptr?
  • Различия между unique_ptr и shared_ptr
  • Каковы потенциальные опасности при использовании boost :: shared_ptr?
  • std :: shared_ptr безопасность streamа объясняется
  • C ++ - передача ссылок на std :: shared_ptr или boost :: shared_ptr
  • Где shared_ptr?
  • Как избежать утечки памяти с помощью shared_ptr?
  • shared_ptr в массив: следует ли его использовать?
  • Давайте будем гением компьютера.