1.整体构造顺序
前面我们提到过,一个类在构造的时候,先会构造其成员变量,在调用自身的构造函数。
对于派生类来说,除了可能有成员变量,还可能有多个基类。在初始化派生类对象时,其构造函数要负责基类与基类成员对象的构造,还要负责自己成员对象的构造。
2.构造格式
前面也提到过,派生类只能使用构造函数初始化列表的方式,向基类与成员变量的构造函数传递参数完成初始化工作。具体形式如下:
派生类构造函数(args):基类构造函数(args),成员对象1(args),成员对象2(args),…
派生类对象构造的顺序为:
1.先构造基类
2.再构造自身成员变量
3.最后调用自身构造函数
基类构造顺序由派生层次决定:最远的基类最先构造 成员构造顺序和定义顺序符合。
而析构函数的析构顺序与构造顺序相反。
3.派生类构造顺序实习
#include<iostream>
using namespace std;
class A {
int a;
public:
A(int a=0) {
this->a = a;
cout<<"a is: "<<this->a<<endl;
}
};
class B {
int b;
public:
B(int b) {
this->b = b;
cout<<"b is: "<<this->b<<endl;
}
};
class C {
int c;
public:
C(int c) {
this->c = c;
cout<<"c is: "<<this->c<<endl;
}
};
class D {
int d;
public:
D(int d) {
this->d = d;
cout<<"d is: "<<this->d<<endl;
}
};
class E : public B, public D {
public:
C c1, c2;
A *a1 = new A(10);
A a2, a3;
E(): a2(2), a3(3), c1(11), c2(22), B(100), D(200) {
cout<<"d is init!"<<endl;
}
};
int main(int argc, char const *argv[])
{
E e;
return 0;
}
代码输出结果:
b is: 100
d is: 200
c is: 11
c is: 22
a is: 10
a is: 2
a is: 3
d is init!
根据上面代码输出结果,再结合第二部分内容,不难看出派生类的实际构造顺序。
4.派生类析构顺序实例
#include<iostream>
#include<string>
using namespace std;
class A {
public:
virtual ~A() { cout<<"call A::~A()"<<endl; }
};
class B: public A {
char *c;
public:
B(int i) {c = new char[i];}
~B() {
delete [] c;
cout<<"call B::~()"<<endl;
}
};
int main(int argc, char const *argv[])
{
A *a = new B(10);
delete a;
return 0;
}
代码运行结果为:
call B::~()
call A::~A()
版权声明:本文为bitcarmanlee原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。