继承

#include <iostream>
#include <cmath>
using namespace std;

class A
{
public:
A(){cout << "Construct A" << endl;}
~A(){cout << "Destruct A" << endl;}
};

class C
{
public:
C(){cout << "Construct C" << endl;}
~C(){cout << "Destruct C" << endl;}
};

class B: public A, public C
{
public:
B(){cout << "Construct B" << endl;}
~B(){cout << "Destruct B" << endl;}
};

int main(int argc, char const *argv[])
{
B b;
return 0;
}

先构造父类,再构造子类,其中父类的构造顺序是从左到右。

Construct A
Construct C
Construct B
Destruct B
Destruct C
Destruct A

类图


列表初始化

现在ABC之间不再是继承关系,而是组合关系。B类中有A和C两个类型的变量。

#include <iostream>
#include <cmath>
using namespace std;

class A
{
public:
A(){cout << "Construct A" << endl;}
~A(){cout << "Destruct A" << endl;}
};

class C
{
public:
C(){cout << "Construct C" << endl;}
~C(){cout << "Destruct C" << endl;}
};

class B
{
public:
// Notice
B(): a(A()), c(C()) {cout << "Construct B" << endl;}
~B(){cout << "Destruct B" << endl;}
C c;
A a;
};

int main(int argc, char const *argv[])
{
B b;
return 0;
}

列表初始化是先于构造函数的调用的,而且列表初始化是与初始化顺序无关,只与数据成员定义的顺序有关

Construct C
Construct A
Construct B
Destruct B
Destruct A
Destruct C

继承与列表初始化

下面的例子中B类继承了A和C,然后又拥有一个A和C类型的成员变量,虽然不符合设计模式,但是就将就看了。

#include <iostream>
#include <cmath>
using namespace std;

class A
{
public:
A(){cout << "Construct A" << endl;}
~A(){cout << "Destruct A" << endl;}
};

class C
{
public:
C(){cout << "Construct C" << endl;}
~C(){cout << "Destruct C" << endl;}
};

class B: public A, public C
{
public:
//Notice: List initialize
B(): a(A()), c(C()) {cout << "Construct B" << endl;}
~B(){cout << "Destruct B" << endl;}
C c;
A a;
};

int main(int argc, char const *argv[])
{
B b;
return 0;
}

类在构造的时候会先从左到右调用父类的构造函数,然后根据类中数据成员的定义依次构造

Construct A
Construct C
Construct C
Construct A
Construct B
Destruct B
Destruct A
Destruct C
Destruct C
Destruct A

虚拟继承,继承,与列表初始化

#include <iostream>
#include <cmath>
using namespace std;

class A
{
public:
A(){cout << "Construct A" << endl;}
~A(){cout << "Destruct A" << endl;}
};

class C
{
public:
C(){cout << "Construct C" << endl;}
~C(){cout << "Destruct C" << endl;}
};

//Notice: C is a virtual public
class B: public A, public virtual C
{
public:
B(): a(A()), c(C()) {cout << "Construct B" << endl;}
~B(){cout << "Destruct B" << endl;}
C c;
A a;
};

int main(int argc, char const *argv[])
{
B b;
return 0;
}

先执行虚拟继承的父类的构造函数,然后从左到右执行普通继承的父类的构造函数,然后按照定义的顺序执行数据成员的初始化,最后是自身的构造函数的调用。

Construct C
Construct A
Construct C
Construct A
Construct B
Destruct B
Destruct A
Destruct C
Destruct A
Destruct C

一个例子


class Base {
public:
Base() { cout << " this is Base" << endl; }
};

class VBase1 {
public:
VBase1() { cout << " this is VBase1" << endl; }
};

class VBase2 {
public:
VBase2() { cout << " this is VBase2" << endl; }
};

class A : public Base, virtual public VBase1, virtual public VBase2 {
public:
A() { cout << " this is A " << endl; }
};

class B {
public:
B() { cout << " this is B" << endl; }
};

class C {
public:
C() { cout << " this is C" << endl; }
};

class E {
public:
E() { cout << " this is E " << endl; }
};

class D : public B, public A {
public:
D() { cout << " this is D" << endl; }

private:
C c;
E e;
};

int main() {
D d = D();

return 0;
}

在这里插入图片描述

执行虚基类的构造函数(不管是几重继承),执行的顺序是虚基类继承的顺序

B比Base优先;


再来一个例子

https://blog.csdn.net/qq_45532226/article/details/105278043

#include <iostream>

using namespace std;

class X {
public:
X() { cout << "X "; }
};
class Y {
public:
Y() { cout << "Y "; }
};
class Z {
public:
Z() { cout << "Z "; }
};
class A {
public:
A() { cout << "A "; }
};
class B {
public:
B() { cout << "B "; }
};
class C : public B, virtual public A {
public:
C() { cout << "C "; }
};
class D : public B, virtual public A {
public:
D() { cout << "D "; }
};
class E : public C, virtual public D, virtual public Z {
public:
X objX;
Y objY;
E() { cout << "E "; }
};
int main() {
E obj;
system("pause");
}

B A. B A.

C D. Z.

​ (XY)E

A B! D Z B C X Y E