调用派生类的析构函数

时间:2012-09-05 17:19:27

标签: c++

为什么在此代码中调用Derived类的析构函数?

#include <iostream>

class Base
{
public:
   Base() { std::cout << "Base::Base() \n"; }
   ~Base() { std::cout << "Base::~Base() \n"; } 
};

class Derived : public Base
{
public:
   Derived() { std::cout << "Derived::Derived() \n"; }
   ~Derived() { std::cout << "Derived::~Derived() \n"; } 
};

Derived foo() { return Derived(); }

int main()
{
   const Derived& instance = foo();
}

2 个答案:

答案 0 :(得分:3)

  

为什么在此代码中调用Derived类的析构函数?

因为Derived中创建的foo()实例在主程序结束时超出了范围。

#include <iostream>
using namespace std;

class Base {
public:
    Base() {
        std::cout << "Base::Base() \n";
    }
    ~Base() {
        std::cout << "Base::~Base() \n";
    }
};

class Derived: public Base {
public:
    int i;
    Derived() {
        i = 10;
        std::cout << "Derived::Derived() \n";
    }
    ~Derived() {
        i = 0;
        std::cout << "Derived::~Derived() \n";
    }
    int get() {
        return i;
    }
};

Derived foo() {
    return Derived();
}

int main() {
    const Derived& instance = foo();
    cout << instance.i << endl;
    return 0;
}

输出如下:

Base::Base()
Derived::Derived()
10
Derived::~Derived()
Base::~Base()

答案 1 :(得分:3)

为了让它更有趣,请考虑修改后的main

const Base& instance = foo();

该代码创建类型为foo的临时(由Derived返回的对象)并通过将其绑定到类型Base的常量引用来延长对象的生命周期。临时的生命周期将延长,直到引用超出范围,此时对象将被销毁。代码大致翻译为:

Derived __tmp = foo();
const Base& instance = __tmp;

在持有引用instance的块的末尾,__tmp变量也超出范围并被删除。请注意,即使没有虚析构函数,也会调用相应的析构函数,因为__tmp的类型为Derived(函数返回的类型)。