Czy istnieje różnica między pustym a null shared_ptr?
Empty shared_ptr
nie ma bloku kontrolnego, a jego licznik użycia uważany jest za 0. Kopia pustego shared_ptr
to kolejny pusty shared_ptr
. Oba są oddzielnymi shared_ptr
elementami, które nie mają wspólnego bloku sterującego, ponieważ go nie mają. Empty shared_ptr
można skonstruować za pomocą domyślnego konstruktora lub konstruktora, który pobiera nullptr
.
Niepusty null shared_ptr
ma blok kontrolny, który może być współdzielony z innymi shared_ptr
s. Kopia niepustej wartości null shared_ptr
jest shared_ptr
taka, że dzieli ten sam blok kontrolny co oryginał, shared_ptr
więc liczba użytych wartości nie jest równa 0. Można powiedzieć, że wszystkie kopie shared_ptr
mają takie samenullptr
. Niepusty null shared_ptr
można skonstruować za pomocą pustego wskaźnika typu obiektu (nie nullptr
)
Oto przykład:
#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;
}
Wyprowadza:
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
shared_ptr
instancji z przechowywanym wskaźnikiem innym niż NULL”. Warto również wspomnieć o poprzedniej uwadze (s. 15), „Aby uniknąć możliwości wiszącego wskaźnika, użytkownik tego konstruktora musi zapewnić, żep
pozostanie on ważny przynajmniej do momentur
zniszczenia grupy własności ”. Rzeczywiście rzadko używana konstrukcja.