c++ memory-management pointers shared-ptr auto-ptr

C++: auto_ptr+declaración adelante?



memory-management pointers (7)

Tengo una clase como esta:

class Inner; class Cont { public: Cont(); virtual ~Cont(); private: Inner* m_inner; };

en .cpp, el constructor crea una instancia de Inner con new y el destructor la delete . Esto está funcionando bastante bien.
Ahora quiero cambiar este código para usar auto_ptr así que escribo:

class Inner; class Cont { public: Cont(); virtual ~Cont(); private: std::auto_ptr<Inner> m_inner; };

Ahora, el constructor inicializó el auto_ptr y el destructor no hace nada.

Pero no funciona. el problema parece surgir cuando estoy instanciando esta clase. Recibo esta advertencia:

advertencia C4150: eliminación del puntero a tipo incompleto ''Inner''; no hay destructor llamado

Bueno, esto es obviamente muy malo y entiendo por qué sucede, el compilador no sabe sobre el tema de Inner al crear la plantilla de auto_ptr<Inner>

Entonces mi pregunta es: ¿hay alguna manera de usar auto_ptr con una declaración forward como lo hice en la versión que usa simplemente punteros?
Tener que #include todas las clases a las que declaro un puntero es una gran molestia y, a veces, simplemente imposible. ¿Cómo se maneja este problema generalmente?


Parece ser ridículo, pero resolví el mismo problema añadiendo #include <memory> al archivo Cont.h.


Debe incluir el encabezado que define la class Inner en el archivo donde se encuentra la implementación Cont::~Cont() . De esta forma, todavía tiene una declaración directa en el encabezado que define la class Cont y el compilador ve class Inner definición class Inner y puede llamar al destructor.

//Cont.h class Inner; // is defined in Inner.h class Cont { virtual ~Cont(); std::auto_ptr<Inner> m_inner; }; // Cont.cpp #include <Cont.h> #include <Inner.h> Cont::~Cont() { }


Puede considerar boost :: shared_ptr () en su lugar. No tiene desventajas prácticas en lugar de rendimiento, y es mucho más amigable para enviar declaraciones:

boost::shared_ptr<class NeverHeardNameBefore> ptr;

está bien, sin declaraciones adicionales arriba.

shared_ptr hace más que auto_ptr, como el recuento de referencias, pero no debería dañar si no lo necesitas.


No se supone técnicamente que cree instancias de plantillas de biblioteca estándar con tipos incompletos, aunque no conozco ninguna implementación en la que esto no funcione. En la práctica, la respuesta de Sharptooth es lo que también recomendaría.

Realmente no había nada de malo con el uso de un puntero desnudo para su puntero impl, siempre que invoque eliminar en su destructor. Probablemente también deba implementar o deshabilitar el constructor de copias y el operador de asignación.


Resulta que el problema ocurre solo cuando hago el c''tor en línea. Si pongo el c''tor en el cpp, después de la declinación de Inner todo está bien.


La declaración directa en el encabezado está bien si implementa el destructor en el archivo cont.cpp e incluye inner.h, como otros señalaron.

El problema podría estar en el uso de Cont. En cada cpp que usa (y destruye) Cont, debe incluir cont.h AND inner.h. Eso resolvió el problema en mi caso.


Esta pregunta (eliminación de objeto con destructor privado) y esta pregunta (cómo escribir una plantilla completa) pueden ser de ayuda.