2010-06-20 17 views
9

en el siguiente código:C++ debe eliminar una referencia?

class x 
{ 
private: 
someRef& m_ref; 

public: 
x(someRef& someRef):m_ref(someRef) 
{ 
} 

necesito para hacer:

~x() 
{ 
    delete m_ref; 
} 

que, por la obra forma duerma sin obtener el puntero ...

básicamente lo que te pido: ¿Debo llamar a un destructor en un miembro de referencia?

+0

ese trozo de código incluso no compilar –

+0

En caso de duda, eche un vistazo a shared_ptr [1], que se hará cargo de todas sus referencias y punteros para usted. [1] http://www.boost.org/doc/libs/1_43_0/libs/smart_ptr/shared_ptr.htm – Gianni

Respuesta

3

No. Solo puede eliminar punteros, no referencias, e incluso solo debe eliminar los objetos que asignó utilizando el operador new. Y luego debes asegurarte de borrarlos solo una vez. Aquí es el caso en el que tendría que usar delete en su destructor:

class x 
{ 
private: 
someObj* m_ptr; 

public: 
x():m_ptr(new someObj()) 
{ 
} 

~x() 
{ 
    delete m_ptr; 
} 

Pero, en general, lo mejor es evitar incluso esto y utilizar punteros inteligentes lugar.

+0

solo para aclarar, si se llama al destructor del padre, ¿también llamará a los destructores de miembros que se pasaron por referencia? Supongo que no porque no fue inicializado por la clase, pero podría estar equivocado. – Mel

+0

¿Cómo se relaciona esto con las variables de referencia? –

16

Sólo es necesario delete un objeto si le pertenece. Si le pasaron una referencia, significa que alguien más la posee, por lo tanto, es innecesario y afortunadamente el lenguaje lo impide.

+2

¿Cómo lo previene el idioma? – Troubadour

+0

@Troubadour 'foo & a; delete a;' fallará (excepto cuando foo es un tipo de puntero). – tstenner

+0

@Troubadour: como mencionó el OP, simplemente no compila. –

6

No creo que uno realmente en sentido estricto alguna vez borre incluso los punteros. Lo que elimina son objetos dinámicamente asignados (o matrices de objetos) para los que el puntero es un identificador. Si el objeto se origina de una llamada al nuevo y es la responsabilidad de esta clase limpiar después de este objeto, entonces llame al borre.

es técnicamente posible que una referencia puede estar refiriéndose a un objeto asignado dinámicamente:

int main() 
{ 
    //in principle a reference can also refer to a dynamically allocated object 
    x var(*new someRef); 
} 

//and if that is the intended usage: 
x::~x() 
{ 
    delete &m_ref; 
} 

Sin embargo, esto sería muy mal estilo. Por convención, el identificador "propietario" de un objeto dinámicamente asignado no debe ser una referencia.

2

quiero aclarar algunos conceptos erróneos que parecen tener que están más allá de la intención de su pregunta:

Cuando destructor de una clase se llama todos los destructores de los miembros que ser llamado así.

Llamar a delete no es lo mismo que llamar al destructor. delete llama explícitamente al destructor y también llama al operator delete en la ubicación de los objetos, es una cosa de 2 partes.

+0

solo para aclarar, usted mencionó 'todos los destructores de miembros son llamados también'. ¿Esto incluye miembros que fueron pasados ​​por referencia en el constructor? Supongo que no lo hará porque estos objetos no son propiedad de la clase y es probablemente el propietario del llamador del constructor. – Mel

+0

@Mel Es probable que aquí se aplique una cotización estándar que las referencias se tratan como primitivas y no tienen destructores. En cualquier caso, su suposición es correcta. – David

1

Para un pequeño fragmento de una aclaración adicional que quieren ofrecer lo siguiente:

int *pi = new int; 

//int& ir = pi; // can't do 
       // this a reference to the pointer but it is an error 
       // because or the type difference int& vs int* and 
       // static_cast won't help. reinterpret_cast would allow 
       // the assignment to take place but not help the 'delete ir' 

int& ir = *pi; // this is OK - a reference to what the pointer points to. 
       // In other words, the the address of the int on the heap. 

//delete ir; // can't do, it is a reference and you can't delete non-pointers. 

delete &ir;  // this works but it is still not "deleting a reference". 
       // The reference 'ir' is another name for the heap-based int. 
       // So, &ir is the address of that int, essentially a pointer. 
       // It is a pointer that is being used by delete, not a reference. 
+0

"la dirección del int en el montón">. < –

+0

De hecho, estrictamente hablando, nunca "borras un puntero". Borre objetos asignados dinámicamente pasándoles punteros para 'eliminar'. –

Cuestiones relacionadas