¿Hay alguna diferencia entre un shared_ptr vacío y uno nulo?
Empty shared_ptrno tiene bloque de control y su recuento de uso se considera 0. La copia de empty shared_ptres otro vacío shared_ptr. Ambos son correos shared_ptrelectrónicos separados que no comparten un bloque de control común porque no lo tienen. Empty shared_ptrse puede construir con el constructor predeterminado o con el constructor que toma nullptr.
El nulo no vacío shared_ptrtiene un bloque de control que se puede compartir con otros shared_ptrs. La copia de nulo no vacío shared_ptres shared_ptrque comparte el mismo bloque de control que el original, shared_ptrpor lo que el recuento de uso no es 0. Se puede decir que todas las copias de shared_ptrcomparten lo mismonullptr . Se shared_ptrpuede construir un nulo no vacío con un puntero nulo del tipo de objeto (no nullptr)
He aquí un ejemplo:
#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;
}
Produce:
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_ptrinstancia vacía con un puntero almacenado no NULL". También vale la pena mencionar la nota anterior (p15), "Para evitar la posibilidad de un puntero colgando, el usuario de este constructor debe asegurarse de quepsigue siendo válido al menos hasta querse destruya el grupo de propiedad de ". De hecho, una construcción poco utilizada.