В чем разница между пустым и нулевым std::shared ptr в C++?
The cplusplus.com shared_ptr страница вызывает различие между пустойstd::shared_ptr и nullshared_ptr. The cppreference.com страница явно не вызывает различие, но использует как "пустой", так и сравнение с nullptr в описании std::shared_ptr поведение.
есть ли разница между пустым и нулевым shared_ptr? Есть ли какой-либо вариант использования для таких указателей смешанного поведения? Совсем не пустой null shared_ptr смысла? Будет ли когда-нибудь случай в обычном использовании (т. е. если вы явно не построили его), где вы можете получить пустой, но ненулевой shared_ptr?
и изменится ли какой-либо из этих ответов, если вы используете версию Boost вместо версии C++11?
2 ответов:
это странный уголок
shared_ptrповедение. Он имеет конструктор, который позволяет сделатьshared_ptrчто принадлежит а то указывает на другое:template< class Y > shared_ptr( const shared_ptr<Y>& r, T *ptr );The
shared_ptrпостроить с помощью этого конструктора доли Сr, а указывает на всеptrуказывает на (т. е. вызовget()илиoperator->()вернутсяptr). Это удобно для случаев, когдаptrуказывает на подобъект (например, элемент данных) объекта, принадлежащегоr.страница, которую вы связали, вызывает
shared_ptrкоторому ничего не принадлежит пустой иshared_ptrэто ни на что не указывает (т. е. чейget() == nullptr) null. (пустой используется в этом смысле стандартом; null нет.) вы можете построить null-but-not-emptyshared_ptr, но это будет не очень полезно. Пустой-но-не-нульshared_ptrявляется по существу не владеющим указателем, который может быть использован, чтобы сделать некоторые странные вещи, как передача указателя на что-то выделенное в стеке функции, ожидающейshared_ptr(но я бы предложил ударить того, кто поставилshared_ptrсначала внутри API).
boost::shared_ptrи этот конструктор, которую они называют конструктор ступенчатость.
есть ли разница между пустым и нулевым shared_ptr?
пустой
shared_ptrне имеет блока управления и его количество использования считается равным 0. Копия пустойshared_ptrеще один пустойshared_ptr. Они оба раздельныеshared_ptrs, которые не имеют общего блока управления, потому что у них его нет. Пустоshared_ptrможет быть построен с конструктором по умолчанию или с конструктором, который принимаетnullptr.непустой null
shared_ptrконтроль блок, который может быть разделен с другимиshared_ptrы. Копия непустых значений nullshared_ptrиshared_ptr, который разделяет тот же блок управления, как оригиналshared_ptrТак что используйте count не 0. можно сказать, что все копииshared_ptrодинаковыеnullptr. Непустой nullshared_ptrможет быть построен с нулевым указателем типа объекта (неnullptr)вот пример:
#include <iostream> #include <memory> int main() { std::cout << "std::shared_ptr<int> ptr1:" << std::endl; { std::shared_ptr<int> ptr1; std::cout << "\tuse count before copying ptr: " << ptr1.use_count() << std::endl; std::shared_ptr<int> 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<int> ptr1(nullptr):" << std::endl; { std::shared_ptr<int> ptr1(nullptr); std::cout << "\tuse count before copying ptr: " << ptr1.use_count() << std::endl; std::shared_ptr<int> 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<int> ptr1(static_cast<int*>(nullptr))" << std::endl; { std::shared_ptr<int> ptr1(static_cast<int*>(nullptr)); std::cout << "\tuse count before copying ptr: " << ptr1.use_count() << std::endl; std::shared_ptr<int> 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<int> ptr1: use count before copying ptr: 0 use count after copying ptr: 0 ptr1 is null std::shared_ptr<int> ptr1(nullptr): use count before copying ptr: 0 use count after copying ptr: 0 ptr1 is null std::shared_ptr<int> ptr1(static_cast<int*>(nullptr)) use count before copying ptr: 1 use count after copying ptr: 2 ptr1 is null
Comments