2
#include <iostream>
#include <string>

using namespace std;

class Person
{
    string name;

    public:
        Person():name("")
        {
            cout << "Person default ctor\n";
        }
        Person(const string& name_in):name(name_in)
        {
            cout << "Person string ctor: " << name << "\n";
        }
        ~Person()
        {
            cout << "Person dtor: " << name << "\n";
        }
        string get_name()
        {
            return name;
        }
};

class Professor:public Person
{
    int office;

    public:
        Professor(const string& name_in, int office_in):Person(name_in), office(office_in)
        {
            cout << "Professor string ctor: " << get_name() << endl;
        }
        ~Professor()
        {
            cout << "Professor dtro: " << get_name() << endl;
        }
};

int main()
{
    Person alice("Alice");
    Professor bob("Bob", 10);

    return 0;
}

我假设输出应该是:

Person string ctor: Alice

Person dtor: Alice

Professor string ctor: Bob

Professor dtor: Bob

因为这似乎应该从程序的结构逻辑上遵循。然而,真正的输出是:

Person string ctor: Alice

Person string ctor: Bob

Professor string ctor: Bob

Professor dtor: Bob

Person dtor: Bob

Person dtor: Alice

有人可以解释这是为什么吗?我对类/构造函数/析构函数有什么不了解,这让我想出了错误的输出?

4

3 回答 3

6

首先,Professor来源于Person。这意味着每个实例都Professor隐含地包含一个实例Person(观察你是如何Person(name_in)Professor的构造函数中调用的)。Professor当对象被销毁时,这个隐式实例将自动被销毁。

这解释了为什么您会看到:

Person string ctor: Bob
Person dtor: Bob

至于析构函数调用的顺序,变量的销毁顺序与构造的相反。这就解释了为什么 Bob 在 Alice 之前就被销毁了:

Person string ctor: Alice
Professor string ctor: Bob
Professor dtor: Bob
Person dtor: Alice
于 2012-11-26T23:10:07.620 回答
0

教授“是”人,所以当你调用教授构造函数时,它的基类的构造函数——即Person——将首先被调用。

类似于破坏者,但顺序相反。子类的析构函数将首先被调用,然后是基类。

此外,仅在对象被销毁时才调用析构函数,在您的情况下,仅在当前范围结束时才会发生。

于 2012-11-26T23:16:07.413 回答
0

因为Professor是继承的,所以在创建时会调用基类构造函数。这就是为什么person Bob要打印。

至于反向销毁,这是因为对象的销毁顺序与创建它们的顺序相反。

于 2012-11-26T23:11:16.400 回答