2012-05-29 10 views
7

que tienen la siguiente clase:referencia y destructor en C++

class A 
{ 
public: 
    B& getB() {return b;}  
private: 
    B b; 
}; 

class B 
{ 
    ~B() {cout<<"destructor B is called";} 
... 

}; 

void func() 
{ 
    A *a = new a; 
    B b = a->getB(); 
    ..... 
} 

¿Por qué el destructor de la clase B se llama al salir de la función func? ¿La función getB devuelve un referance al objeto B? si todavía existe la clase A al final de la función func, ¿por qué se llama al destructor de B?

+0

Su objeto b sigue siendo local para la función. –

Respuesta

6

Cuando se tiene:

B b = a->getB(); 

se crea un nuevo objeto de tipo B a partir de una referencia a la instancia existente de B (B&). No es el B::operator= que se llama aquí pero copia constructor.

Cada clase tiene un constructor de copia (si no lo agrega explícitamente, el compilador proporcionará uno para usted). Acepta un único argumento que es una referencia a la misma clase. Usted no ha puesto constructor de copia en el código anterior, así que supongo que el compilador ha generado una para ti:

class B 
{ 
public: 
    B(B& other) 
    { 
     // memberwise copy (shallow copy) 
    }; 
}; 

Así A::getB() devuelve una referencia al miembro A::b y esta referencia se pasa como argumento a B::B(B&).

void func() 
{ 
    A *a = new A(); // Instance of A is created on the heap; 
        // (pointer a is a local variable and is on the stack though!) 
        // A::b is object of type B and it is on the heap as well 

    B b = a->getB(); // Instance of class B is created on the stack (local variable) 
    ..... 
    delete a;  // deleting A from the heap: 
        // A::~A is called which calls B::~B (of its member b) 
} // a and b go out of the scope; b is an object => B::~B is called      
+0

entonces, ¿para qué sirve devolver por referencia desde una función si se crea un nuevo objeto? – Shay

+0

@Shay: el objeto se devuelve por referencia para que evite la copia del objeto como al devolver por valor, pero esta referencia devuelta se copia para crear un nuevo objeto en la pila que luego se inicializa utilizando la referencia devuelta. –

20
B b = a->getB(); 

va a llamar el constructor de copia B(const& B) por lo que está creando un nuevo objeto en la pila con una copia del objeto devuelto por la referencia. usar en su lugar:

B& b = a->getB(); 

y no destructor será llamado, ya que no va a crear un nuevo objeto B

+0

¿Una copia de la referencia significa una copia de la dirección de B? – Shay

+0

@chaiy no lo creo, simplemente llama al constructor de copias – lezebulon

+2

@Shay no, esta respuesta es engañosa. Significa una copia de * el objeto *. –