ссылка и деструктор в 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();
   .....
}

почему деструктор класса B вызывается при выходе из функции func? Делаешь функцию getB вернуть referance к объекту Б? если класс A все еще существует в конце функции func, почему вызывается деструктор B?

2 ответов


если вы:

B b = a->getB();

новый объект типа B создается из ссылки на существующий экземпляр B (B&). Это не B::operator= это называется здесь, но конструктор копирования.

каждый класс имеет конструктор копирования (если вы не добавляете его явно, компилятор предоставит его для вас). Он принимает один аргумент, который является ссылкой на тот же класс. Вы не поместили конструктор копирования в код выше, поэтому я предполагаю этот компилятор создал один для вас:

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

так A::getB() возвращена ссылка на member A::b и эта ссылка была передана как аргумент 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                    

 B b = a->getB();

будет вызывать конструктор копирования B(const& B) таким образом, вы создаете новый объект в стеке с копией объекта, возвращаемого ссылкой. Вместо этого используйте:

 B& b = a->getB();

и деструктор не будет вызван, так как вы не создаете новый объект B