2011-02-07 10 views
14

¿Por qué puedo crear un objeto de una clase con un destructor privado en la tienda gratuita pero no en la pila?Destructor privado

Por ejemplo, esto es ilegal:

class Foo 
{ 
public: 
    explicit Foo(int); 
    static void delete_foo(Foo* foo) { delete foo; } 
private: 
    int x; 
    ~Foo(); 
    Foo(const Foo&); 
    Foo& operator=(const Foo&); 
}; 

int main() 
{ 
    Foo * fooptr = new Foo(5); // legal 
    Foo::delete_foo(fooptr); // legal 
    Foo foo(5); // illegal 
} 
+0

¿Podría proporcionarnos un ejemplo de código breve para la ilustración? – sharptooth

+0

Puedo hacer eso por usted – CashCow

Respuesta

18

Cuando se crea en la pila, debe ser destruido antes de que la función puede devolver. Suponiendo que la función en cuestión no tiene acceso al destructor, esto no está permitido.

Al crearlo en la tienda gratuita, se deja para que otro código, que tiene acceso al destructor, lo destruya.

Una función miembro de una clase con un destructor privado puede crear una instancia en la pila. Una función miembro estática incluso se puede llamar sin una instancia preexistente. Sin embargo, probablemente no haya una buena razón para escribir tal cosa.

+0

+1 por el matiz de la función miembro. – GManNickG

+1

@Potatoswatter: puede ser útil forzar al usuario a acceder al objeto a través de un proxy "amigo". Parece limitado sin embargo. –

+1

@ Matthieu: Sí, debería haber mencionado eso. Hay buenas razones para escribir un destructor privado.Solo quise decir que rara vez una función miembro estática creará una instancia temporal, o tal objeto se colocará en la pila. – Potatoswatter

2

Porque crear un objeto en la tienda gratuita no requiere un destructor público, pero crearlo en la pila sí lo hace porque los objetos se destruirán cuando salga del alcance. Puede crear el objeto en la tienda gratuita, pero no puede eliminarlo, por lo que tendrá una pérdida de memoria a menos que el objeto o una función amiga lo destruya.

9

Porque un objeto con almacenamiento automático * necesita ser, bueno, automáticamente destruido. Entonces el destructor necesita estar disponible para llamar; si no es así, no puede tener ese tipo en almacenamiento automático.

Por el contrario, le corresponde a usted eliminarlo cuando lo asigna dinámicamente. Por supuesto, no puedes hacerlo.

* Los objetos aquí son, en las plataformas "típicas", comúnmente asignados en la pila.

1

Puede crear uno en la pila solo en el ámbito que tiene acceso al destructor. Por lo tanto, puede hacerlo en una función de amigo o función miembro estática de la clase (o incluso un miembro de la clase regular).

El final de la función para una variable local es responsable de eliminar, por lo tanto, debe poder llamar al destructor, aunque implícitamente.

Puede crear uno con nuevo desde cualquier lugar si tiene acceso al constructor apropiado.

Si lo usa en un puntero inteligente, debe asegurarse de que adonde se elimine tenga acceso. Esto puede variar para diferentes smart-pointers, y para algunos puede proporcionar un destructor personalizado que podría ser un miembro estático de la clase.

0

Porque puede entonces exigir que un objeto siempre se asigne dinámicamente, es decir, con un nuevo operador. Para que funcione, necesitaría implementar un método de eliminación() que llame a "eliminar esto" antes de que regrese. Esto permite crear métodos de finalización a los que se llama antes de que se destruya un objeto o una parte de un objeto, y así puede eliminar o desconectar de forma segura los miembros de la instancia antes de que se llame a la cadena de destructores virtuales.