2012-05-29 17 views
7

Ho la seguente classe:riferimento e distruttore in 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(); 
    ..... 
} 

Perché il distruttore della classe B viene chiamato quando si esce la funzione func? Doest la funzione getB restituisce un riferimento all'oggetto B? se la classe A esiste ancora alla fine della funzione func, perché viene chiamato il distruttore di B?

+0

L'oggetto b è ancora locale alla funzione. –

risposta

6

Quando si dispone di:

B b = a->getB(); 

viene creato un nuovo oggetto di tipo B da un riferimento all'istanza esistente di B (B&). Non è lo B::operator= chiamato qui ma il costruttore di copie .

Ogni classe ha un costruttore di copie (se non lo si specifica esplicitamente, il compilatore ne fornirà uno). Accetta un singolo argomento che è un riferimento alla stessa classe. Non hai messo costruttore di copia nel codice sopra quindi immagino che il compilatore ha generato uno per te:

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

Così A::getB() tornato un riferimento al membro A::b e questo riferimento è stato passato come argomento 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

quindi che uso fa il ritorno per riferimento da una funzione se viene creato un nuovo oggetto? – Shay

+0

@Shay: l'oggetto viene restituito per riferimento in modo da evitare la copia dell'oggetto come durante la restituzione per valore, ma questo riferimento restituito viene quindi copiato per creare un nuovo oggetto sullo stack che viene quindi inizializzato utilizzando il riferimento restituito. –

20
B b = a->getB(); 

chiamerà il costruttore di copia B(const& B) modo si crea un nuovo oggetto sullo stack con una copia dell'oggetto restituito dal riferimento. Usa invece:

B& b = a->getB(); 

e non distruttore sarà chiamato dal momento che non creare un nuovo oggetto B

+0

Una copia del riferimento indica una copia dell'indirizzo di B? – Shay

+0

@chaiy non la penso così, chiameresti semplicemente il costruttore di copie – lezebulon

+2

@Shay no, questa risposta è fuorviante. Significa una copia di * l'oggetto *. –

Problemi correlati