2012-05-29 18 views
7

Ben şu sınıf var:referans ve yıkı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(); 
    ..... 
} 
fonksiyon fonk çıkarken neden B sınıfı yıkıcı adlı mu

? GetB işlevi, B nesnesine bir geri bildirim döndürür mü? Eğer A sınıfı fonksiyonun sonunda hala var ise, B'nin yıkıcısı neden çağrılır?

+0

B nesnesinin işlevi yine de yereldir. –

cevap

6

oluşturmaz çünkü adı verilecek:

B b = a->getB(); 

tip B yeni bir nesne oluşturulur referanstan mevcut örneğe B (B&). Bu, kopya kurucusu adlı burada çağrılan B::operator= değil.

Her sınıfın bir kopya kurucusu vardır (bunu açıkça eklemezseniz, derleyici sizin için bir tane sağlayacaktır). Aynı sınıfa atıfta bulunan tek bir argümanı kabul eder. bu yüzden bu derleyici sizin için bir tane üretti varsayalım Yukarıdaki kodda kopya kurucu koymak değil:

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

Yani A::getB() üyesi A::b bir başvuru döndü ve bu referans B::B(B&) bir argüman olarak kabul edildi.

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

Yani yeni bir nesne oluşturulduğunda, bir işlevden referans alınarak ne dönüyor? – Shay

+0

@Shay: Nesne başvuruya göre döndürülür, bu nedenle nesnenin kopyasına, değere dönerken olduğu gibi koparılır, ancak bu döndürülen başvuru daha sonra yığın üzerinde yeni bir nesne oluşturmak için kopyalanır ve sonra döndürülen başvuru kullanılarak başlatılır. –

20
B b = a->getB(); 

referans ile döndürülen nesnenin bir kopyasını ile böylece yığın üzerinde yeni bir nesne oluştururken kopya kurucu B(const& B) arayacaktır. yerine Kullanım:

B& b = a->getB(); 

ve hiçbir yıkıcı Eğer varsa, yeni bir B nesnesi

+0

Referansın bir kopyası, B adresinin bir kopyası anlamına gelir? – Shay

+0

@chaiy öyle düşünmüyorsanız, kopya oluşturucu – lezebulon

+2

@Shay no'yu çağırmalısınız, bu cevap yanıltıcıdır. * Nesnenin * bir kopyası anlamına gelir. –