shared_ptr make_shared example c++ boost null pointers shared-ptr

make_shared - shared_ptr c++



Puntero NULL con boost:: shared_ptr? (6)

¿Cuál es el equivalente a lo siguiente?

std::vector<Foo*> vec; vec.push_back(NULL);

cuando se trata de boost::shared_ptr ? ¿Es el siguiente código?

std::vector< boost::shared_ptr<Foo> > vec; vec.push_back(boost::shared_ptr<Foo>());

Nota: puedo rechazar muchos de esos objetos. ¿Debo declarar un objeto static nullPtr global en nullPtr parte? De esta forma, solo uno de ellos debería construirse:

boost::shared_ptr<Foo> nullPtr;


Aquí hay algo que creo que es un poco más simple y funciona bien

(recuerda que typedef es tu amigo):

#include <cstdlib> #include <vector> #include <iostream> #include <boost/shared_ptr.hpp> typedef boost::shared_ptr< std::vector<char> > CharVecHandle; inline CharVecHandle newCharVec(std::vector<char>::size_type size) { return CharVecHandle(new std::vector<char>(size)); } inline CharVecHandle newCharVec(void) { return CharVecHandle(); } int main ( void ) { CharVecHandle cvh = newCharVec(); if (cvh == NULL) std::cout << "It''s NULL" << std::endl; else std::cout << "It''s not NULL" << std::endl; std::vector< CharVecHandle > cvh_vec; cvh_vec.push_back(newCharVec(64)); cvh_vec.push_back(newCharVec()); // or call the NULL constructor directly cvh_vec.push_back(CharVecHandle()); return EXIT_SUCCESS; }


Bueno, esto es legal:

shared_ptr<Foo> foo; /* don''t assign */

Y en este estado, no apunta a nada. Incluso puedes probar esta propiedad:

if (foo) { // it points to something } else { // no it doesn''t }

Entonces, ¿por qué no hacer esto?

std::vector < shared_ptr<Foo> > vec; vec.push_back (shared_ptr<Foo>); // push an unassigned one


En C ++ 0x, puede simplemente convertir de nullptr a std::shared_ptr :

std::vector< boost::shared_ptr<Foo> > vec; vec.push_back(nullptr);


Podría declarar un nullPtr global para shared_ptr<Foo> . Pero si contaminas el espacio de nombre global, ¿cómo llamarías al nullPtr global para shared_ptr<Bar> ?

Normalmente, declaro ptr nulo como estático en la clase del puntero.

#include <boost/shared_ptr.hpp> class Foo; // forward decl typedef boost::shared_ptr<Foo> FooPtr; class Foo { public: static FooPtr Null; } ... // define static in cpp file FooPtr Foo::Null; ... // use Foo Null vec.push_back(Foo::Null);

De esta forma, cada clase tiene un nulo estático.


Sí, declare un puntero nulo estático global.


Su sugerencia (llamar al shared_ptr<T> sin argumentos) es correcta. (Llamar al constructor con el valor 0 es equivalente). No creo que esto sea más lento que llamar a vec.push_back() con un shared_ptr<T> preexistente, ya que se requiere una construcción en ambos casos (ya sea directa construcción o copia-construcción).

Pero si quieres una sintaxis "más agradable", puedes probar el siguiente código:

class { public: template<typename T> operator shared_ptr<T>() { return shared_ptr<T>(); } } nullPtr;

Esto declara un solo objeto global nullPtr , que habilita la siguiente sintaxis natural:

shared_ptr<int> pi(new int(42)); shared_ptr<SomeArbitraryType> psat(new SomeArbitraryType("foonly")); ... pi = nullPtr; psat = nullPtr;

Tenga en cuenta que si usa esto en varias unidades de traducción (archivos fuente), tendrá que dar un nombre a la clase (por ejemplo _shared_null_ptr_type ), mover la definición del objeto nullPtr a un archivo .cpp separado y agregar declaraciones extern en el archivo de encabezado donde se define la clase.