C++:39---继承中构造函数、析构函数的关系

2021-02-03 14:50:42 浏览数 (1)

一、继承中构造函数的关系

  • 如果父类没有构造函数,则子类初始化时不需要构造父类
  • 如果父类有构造函数,则子类初始化自己的构造函数时,要先初始化父类的构造函数
  • 基类的构造函数必须在派生类的构造函数初始化列表来进行初始化
  • 总结:在构造自己(子类)之前,需要先构造父类

演示案例

  • 例如:下面的父类A有构造函数,则子类B在初始化构造函数时,必须要构造父类A
代码语言:javascript复制
class A //父类
{
int a_data;
public:
A(int data) { a_data = data; }
~A() {}//5
};
class B :public A //子类
{
int b_data;
public:
B(int data) :A(10)
{
b_data = data;//3
}
~B() {}//6
};
  • 例如:下面的父类A没有有构造函数,则子类B不需要构造父类
代码语言:javascript复制
class A //父类
{
int a_data;
};
class B :public A //子类
{
int b_data;
public:
B(int data)
{
b_data = data;
}
~B() {}
};

二、若一个类中定义了另一类的构造函数关系

与继承中构造父类的构造函数相类似:

  • 如果类中定义的对象没有构造函数,则该类初始化时不需要构造该对象的构造函数
  • 如果类中定义的对象有构造函数,则该类初始化自己的构造函数时,要先初始化该对象的构造函数

总结:在构造自己之前,需要先构造类内的其他对象

注意事项:

  • 类中定义的其它类对象必须在构造函数的初始化列表初始化,不能在构造函数内部初始化

演示案例:

  • 例如:B类中定义了类M的一个对象,且该类有构造函数。则在B的构造函数执行之前需要先初始化m(先执行该类的构造函数)
代码语言:javascript复制
class M
{
int m_data;
public:
M(int data) { m_data = data; }
~M() {}
};
class B
{
int b_data;
M m;//定义M对象
public:
B(int data):m(20)
{
b_data = data;//3
}
~B() {}//6
};
  • 例如:B类中定义了类M的一个对象,但是M类没有构造函数,所以不需要初始化类M
代码语言:javascript复制
class M
{
int m_data;
};
class B
{
int b_data;
M m;
public:
B(int data)
{
b_data = data;
}
~B() {}
};

三、继承中父、子类的构造函数、析构函数的执行顺序

构造函数执行顺序:

  • 第一步:先构造父类的构造函数
  • 第二步:如果类中定义了其他类的对象,再初始化其他类的构造函数
  • 第三步:最后初始化自己的构造函数

析构函数执行顺序: 与构造函数的执行顺序相反

  • 第一步:先执行自己的析构函数
  • 第二步:如果类中定义了其他类的对象,再执行其他类的析构函数
  • 第三步:最后执行父类的析构函数
  • 成员初始化列表初始化顺序不分先后,可随意调整顺序。但子对象必须在成员初始化列表进行初始化

四、单继承中构造函数、析构函数的执行顺序

下面代码中:

  • 构造函数执行顺序为:2-1-3
  • 析构函数执行顺序为:6-4-5
代码语言:javascript复制
//单继承
class M
{
int m_data;
public:
M(int data) { m_data = data; }//1
~M(){}//4
};
class A
{
int a_data;
public:
A(int data) { a_data = data; }//2
~A(){}//5
};
class B :public A
{
int b_data;
M m;//定义一个子对象
public:
B(int data) :A(10), m(20)//初始化
{
b_data = data;//3
}
~B(){}//6
};

五、 多继承中构造函数、析构函数的执行顺序

下面代码中:

  • 构造函数执行顺序为:1-2-3
  • 析构函数执行顺序为:6-5-4
代码语言:javascript复制
//多继承
class A
{
int a_data;
public:
A(int data) { a_data = data; }//1
~A(){}//4
};
class B
{
int b_data;
public:
B(int data) { b_data = data; }//2
~B(){}//5
};
class C :public A,public B//先继承于A,再继承B
{
int c_data;
public:
C(int data) :A(10),B(20)
{
c_data = data;//3
}
~C(){}//6
};

0 人点赞