Pregunta

Tengo una clase como esta:

class Inner;

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

en el .cpp, el constructor crea una instancia de Inner con new y el destructor deletes TI. Esto está funcionando bastante bien.
Ahora quiero cambiar este código a utilizar auto_ptr así que escribir:

class Inner;

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

Ahora, el constructor inicializa la auto_ptr y el destructor no hace nada.

Pero no funciona. el problema parece surgir cuando estoy una instancia de esta clase. Me sale este aviso:

  

C4150 advertencia: eliminación de puntero a   tipo incompleto 'interior'; No   destructor llamado

Bueno, esto es, obviamente, muy mal y entiendo por qué sucede, el compilador no sabe nada de la d'tor de Inner cuando una instancia de la plantilla de auto_ptr<Inner>

Así que mi pregunta: ¿Hay una manera de utilizar auto_ptr con una declaración hacia adelante como lo hice en la versión que utiliza punteros apenas aclara
? Tener que #include cada clase declaro un puntero a una gran molestia y, a veces, imposible. ¿Cómo se maneja generalmente este problema?

¿Fue útil?

Solución

Es necesario incluir la definición de la cabecera class Inner en el archivo donde se encuentra la implementación Cont::~Cont(). De esta manera usted todavía tiene una declaración hacia adelante en teh class Cont definir encabezado y el compilador ve 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()
{
}

Otros consejos

Ahora resulta que el problema se produce sólo cuando hago la línea c'tor. Si pongo la c'tor en el CPP, después de la decleration de bien.

Inner de todo

Usted puede considerar el impulso :: shared_ptr () en su lugar. No tiene desventajas prácticas en lugar de rendimiento, y es mucho más amigable para reenviar declaraciones:

boost::shared_ptr<class NeverHeardNameBefore> ptr;

Está bien, sin declaraciones adicionales por encima.

shared_ptr hace más de auto_ptr, tales como el recuento de referencias, pero no debe dañar si no lo necesita.

Parece ser ridícula pero resuelto el mismo problema agregando #include <memory> al archivo Cont.h.

La declaración hacia adelante en la cabecera está bien si se implementa el destructor en el archivo cont.cpp y se incluye inner.h, como otros señalaron.

El problema podría estar en el uso de Cont. En cada CPP que utiliza (y destruye) Cont tiene que incluir cont.h Y inner.h. Que resolvió el problema en mi caso.

Esta pregunta (supresión de objeto con destructor privado) y this pregunta (cómo escribir plantilla isComplete) puede ayudarle.

No se supone técnicamente para crear instancias de las plantillas de la biblioteca estándar con tipos incompletas, aunque no conozco ninguna aplicación cuando esto no va a funcionar. En la práctica, la respuesta de Dienteafilado es lo que me gustaría recomendar también.

En realidad no había nada malo en usar un puntero desnuda para el puntero del impl, siempre y cuando se llama a eliminar en él en su destructor. Probablemente debería también aplicar o deshabilitar el operador constructor de copia y asignación.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top