9

我有以下课程:

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();
   .....
}

为什么退出函数func时会调用B类的析构函数?函数 getB 是否返回对对象 B 的引用?如果类 A 在函数 func 的末尾仍然存在,为什么要调用 B 的析构函数?

4

2 回答 2

21
 B b = a->getB();

将调用复制构造函数B(const& B),因此您在堆栈上创建一个新对象,它是引用返回的对象的副本。改用:

 B& b = a->getB();

并且不会调用析构函数,因为您不会创建新的 B 对象

于 2012-05-29T15:00:48.477 回答
7

当你有:

B b = a->getB();

一个类型的新对象是从对( )B的现有实例的引用中创建的。它不是这里调用的,而是复制构造函数BB&B::operator=

每个类都有一个复制构造函数(如果你不显式添加它,编译器会为你提供一个)。它接受一个参数,该参数是对同一类的引用。您没有在上面的代码中放置复制构造函数,所以我假设编译器已经为您生成了一个:

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

所以A::getB()返回了对成员的引用,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                    
于 2012-05-29T15:30:48.373 回答