В чем разница между пустым и нулевым 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?

876   2  

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-empty shared_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ы. Копия непустых значений null shared_ptr и shared_ptr, который разделяет тот же блок управления, как оригинал shared_ptr Так что используйте count не 0. можно сказать, что все копии shared_ptr одинаковые nullptr. Непустой null shared_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

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

Comments

    Ничего не найдено.