派生类的析构函数和构造函数

声明了派生类,就可以进一步声明派生类的对象用于解决问题;但是对象在使用之前必须要初始化,而对派生类的初始化就是对该类的数据成员赋值;派生类的数据成员包括三类:
基类数据成员,新增数据成员,成员对象数据成员(也叫子对象,或者内嵌对象);由于基类的构造函数并没有被继承下来,所以要完成初始化的工作,就要在派生类中添加新的
构造函数。
派生类的构造函数需要以合适的初值作为参数,(1)隐含调用基类和新增的内嵌对象成员的构造函数,来初始化他们各自的数据成员;(2)加入新的语句对新增数据成员初始化;
关键问题:什么时候需要调用定义派生类的构造函数:
1、如果基类定义了带有形参表的构造函数的时候,派生类就要定义构造函数;(这时候提供一个将参数传入基类构造函数的途径,保证在基类进行初始化的时候能够获得必要的数据)
2、如果基类没有定义构造函数,派生类也不必定义构造函数,调用默认的构造函数,这时候新增成员的初始化工作可以放到其他公有函数中完成;
派生类的构造函数的执行顺序如下:
1、调用基类的构造函数,调用的顺序按照他们被继承时声明的顺序,从左到右;
2、调用内嵌成员对象的构造函数,调用顺序按照他们在类中声明的顺序;(如果派生类中有内嵌成员对象,才执行第二步,否则直接执行第三步)
3、派生类的构造函数体中的内容;
例子(多继承,含有内嵌成员对象)
class B1
{
public:
 B1(int i)
 {
  cout<<"constructing B1"<<i<<endl;
 }
};

class B2
{
public:
 B2(int j)
 {
  cout<<"constructing B2"<<j<<endl;
 }
};

class B3
{
public:
 B3()
 {
  cout<<"constructing B3"<<endl;
 }
};

class C :public B2,public B1, public B3
{
public:
 C(int x,int y,int m,int n):B1(x),B2(y),memberB2(m),memberB1(n)
 {
  
 }
private:
 
 B1 memberB1;
 B2 memberB2;
 B3 memberB3;
};

void main()
{
 C c(1,2,3,4);
}
运行结果:
constructing B22
constructing B11
constructing B3
constructing B14
constructing B23
constructing B3

注意:1、如果基类里面没有定义构造函数或者定义了没有参数的构造函数,就不需要给他传递参数。(如B3上就是这样)因此基类B3和B3类成员对象member3就不用写到派生类的构造函数列表中;
2、当不需要对派生类新增成员进行初始化操作时,派生类的构造函数体可以为空;
3、如何初始化子对象呢,不是在声明派生类的时候对他进行初始化,eg. B1 memberB1(8);因为类是抽象类型,只是一个模型,是不能有具体的数据的,而且每一个派生类的子对象
一般是不相同的,所以子对象的初始化是在通过调用派生类时通过调用构造函数来实现的;也就是声明派生类对象的时候进行初始化;

派生类构造函数一般语法形式为:
派生类名:派生类名(参数总表):基类名1(参数表1),基类名2(参数表2),基类名n(参数表n),内嵌对象名1(内嵌对象参数表1),内嵌对象名m(内嵌对象参数表m)
{
 派生类新增成员的初始化语句;
}
注意:本例中基类B1的构造函数需要一个参数,则memberB1也需要一个参数,(因为memberB1也是B1类,在建立的时候也是调用基类的构造函数),派生类的参数只是起到传递的作用;
B2,B3情况类似;

二、派生类的析构函数:
因为析构函数没有参数,基类和派生类都没有,虽然派生类不能继承基类的析构函数,但是系统会自动调用基类和内嵌成员对象的析构函数来实现对基类和内嵌对象的析构;
析构函数的执行顺序:
1、调用派生类普通新增成员的析构函数;
2、调用内嵌成员对象的析构函数;
3、调用基类析构函数;
例子:
class B1
{
public:
 B1(int i)
 {
  cout<<"constructing B1"<<i<<endl;
 }
 ~B1()
 {
  cout<<"destructing B1"<<endl;
 }
};

class B2
{
public:
 B2(int j)
 {
  cout<<"constructing B2"<<j<<endl;
 }
 ~B2()
 {
  cout<<"destructing B2"<<endl;
 }
};

class B3
{
public:
 B3()
 {
  cout<<"constructing B3"<<endl;
 }
 ~B3()
 {
  cout<<"destructing B3"<<endl;
 }
};

class C :public B2,public B1, public B3
{
public:
 C(int x,int y,int m,int n):B1(x),B2(y),memberB2(m),memberB1(n)
 {
  
 }
private:
 
 B1 memberB1;
 B2 memberB2;
 B3 memberB3;
};

void main()
{
 C c(1,2,3,4);
 
}

运行结果:
destructing B3
destructing B2
destructing B1
destructing B3
destructing B1
destructing B2
Press any key to continue

查看调用顺序,正好和构造函数顺序相反;
---------------------
作者:lovemysea
来源:CSDN
原文:https://blog.csdn.net/lovemysea/article/details/5274885
版权声明:本文为博主原创文章,转载请附上博文链接!

posted @ 2019-01-08 13:39  lemaden  阅读(382)  评论(0)    收藏  举报