Gibt es einen Unterschied zwischen einem leeren und einem Null shared_ptr?
Leere shared_ptr
verfügt nicht über Steuerblock und seine Verwendung mitgezählt 0. Kopie des leeren shared_ptr
ist eine andere leer shared_ptr
sein. Sie sind beide getrennt shared_ptr
s, die gemeinsame Steuerblock nicht teilen, weil sie es nicht haben. Leer shared_ptr
kann mit Standardkonstruktor oder mit Konstruktor erstellt werden, der nullptr
übernimmt.
Nicht leer Null shared_ptr
hat Steuerblock, der mit anderen shared_ptr
s geteilt werden kann.Kopie der nicht leeren Null shared_ptr
ist shared_ptr
, die den gleichen Steuerblock wie die ursprüngliche shared_ptr
teilt, so verwenden Sie zählen ist nicht 0. Es kann gesagt werden, dass alle Kopien von shared_ptr
teilen die gleichen nullptr
. Nicht leere null shared_ptr
kann mit Null-Zeiger des Objekttypen (nicht nullptr
)
Hier ist beispielsweise aufgebaut sein:
#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;
}
Es gibt:
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
Bemerkenswert: ** C++ 11 § 20.7.2.2.1 (p16) ** "Hinweis: Dieser Konstruktor erlaubt die Erstellung einer leeren 'shared_ptr'-Instanz mit einem nicht-NULL gespeicherten Zeiger." Erwähnenswert ist auch der vorhergehende Hinweis (S. 15), "Um die Möglichkeit eines Dangling-Pointers zu vermeiden, muss der Benutzer dieses Konstruktors sicherstellen, dass' p' mindestens so lange gültig bleibt, bis die Eigentümergruppe von 'r' zerstört ist." Eine selten genutzte Konstruktion. – WhozCraig
@Cubbi Ein 'shared_ptr', dessen' get() '' 'nullptr' * zurückgibt, vergleicht * gleich mit' nullptr', unabhängig davon, ob es irgendetwas besitzt. –
Ein null-aber-nicht-leeres 'shared_ptr's * kann * nützlich sein, um sicherzustellen, dass eine Funktion ausgeführt wird, sobald alle Besitzer von Zeigern außerhalb des Gültigkeitsbereichs sind (selbst im Falle einer Ausnahme!). Nicht sicher, ob es jetzt eine spezielle Klasse dafür gibt. – coldfix