【问题标题】:Some confusion about the order of constructor call and inheritance关于构造函数调用和继承顺序的一些混淆
【发布时间】:2017-09-19 14:02:11
【问题描述】:

我有以下代码:

class A {
    public:
        A() { cout << "A-C" << endl; }
        ~A(){ cout << "A-D" << endl; }
};

class B {
    public:
        B() { 
            cout << "B-C" << endl; 
        }
        ~B() { 
            cout << "B-D" << endl; 
        } 
};

class C {
    protected:
        A* a;
        B b;
    public: 
        C() {
              a = new A;
              cout << "C-C" << endl; 
            }
        ~C() { 
            delete a;
            cout << "C-D" << endl; 
        }
};

class D : public C {
    protected:
        A a;
        B b;
    public:
        D(){ cout << "D-C" << endl; }
        ~D(){ cout << "D-D" << endl; }
};

int main() {
    D* d = new D;
    B* b = new B;

    delete b;
    delete d;

    system("pause");
    return 0;
}

我对输出的最初想法是:

A-C
C-C
A-C
B-C
D-C
B-C
B-D
D-D
B-D
A-D
A-D
C-D

但这是错误的。 输出实际上是:

B-C
A-C
C-C
A-C
B-C
D-C
B-C
B-D
D-D
B-D
A-D
A-D
C-D
B-D

我不知道为什么程序先调用B的构造函数,最后调用它的析构函数。 我认为构造函数调用的顺序应该是这样的: C的构造函数-> A的构造函数-> B的构造函数-> D的构造函数。

而析构函数调用的顺序是构造函数调用的逆序

谁能告诉我为什么B的构造函数在开始时被调用,而B的析构函数在最后被调用?

【问题讨论】:

  • 等等,为什么输出要先B-Cnew D 调用 C 构造函数,后者调用 A 构造函数。
  • @GillBates 嗯嗯。 C 有一个 B 数据成员,它在构造函数的主体之前初始化。
  • @Quentin 我认为C 中的B 数据成员是一个指针,我的错。
  • @aschepler 是的,op 的意思是他将第二部分作为实际输出,只是措辞不正确。
  • 看来我的讲师说错了lol,他说当类从另一个类继承时,只会在派生类构造函数之前调用基类构造函数......他没有提到基类数据成员的初始化。

标签: c++ oop constructor


【解决方案1】:
B-C
A-C
C-C
A-C
B-C
D-C

这些都是D* d = new D;造成的。

D 构造函数调用C 构造函数,因为CD 的基础。

然后,C 类的数据成员 ab 被初始化,a 是一个指针,因此还没有构造函数调用该数据成员。 b 是一个B 类型的对象,所以B 无参数构造函数被调用,给你第一个B-C


然后在C 构造函数中你说new A,它调用A 的构造函数,它给你A-C,然后是C-C

然后,D 类的数据成员 ab 被初始化,它们都是对象,因此调用了两个构造函数,得到 A-CB-C

最后,D 构造函数被调用,并以D-C 结束。

【讨论】:

  • 非常感谢,你的意思是当类继承另一个类的时候,比如说D继承C,它会先初始化基类的数据成员,然后再调用构造函数数据成员的初始化?
  • @KelvinNg 是的,完全正确。
猜你喜欢
  • 2020-01-12
  • 2017-03-18
  • 2021-11-06
  • 2013-01-29
  • 2011-11-24
  • 2015-02-11
  • 1970-01-01
相关资源
最近更新 更多