详解派生类构造函数与析构函数

派生类构造函数与析构函数

1.派生类构造函数:

派生类不能继承基类的构造函数,必须自己定义构造函数进行新增数据成员初始化工作,如果想同时初始化基类数据成员,必须调用基类构造函数。

(1)简单派生类构造函数:

 1 #include <iostream>
 2 
 3 #include <string>
 4 
 5 using namespace std;
 6 
 7  
 8 
 9 class St1
10 
11 {
12 
13 public:
14 
15 //基类构造函数,初始化成员变量
16 
17          St1(int n, string na, char se):num(n),name(na),sex(se){cout<<"St1"<<endl;}
18 
19          ~St1(){cout<<"~St1"<<endl;}
20 
21 protected:
22 
23          int num;
24 
25          string name;
26 
27          char sex;
28 
29 };
30 
31  
32 
33 class St2:public St1
34 
35 {
36 
37 public:
38 
39 //派生类调用基类构造函数
40 
41          St2(int n, string na, char se, int a, string add):St1(n,na,se),age(a),addr(add){cout<<"St2"<<endl;}
42 
43          ~St2(){cout<<"~St2"<<endl;}
44 
45          void display(){cout<<num<<'\t'<<name<<'\t'<<sex<<'\t'<<age<<'\t'<<addr<<endl; }
46 
47 private:
48 
49          int age;
50 
51          string addr;
52 
53 };
54 
55 int main()
56 
57 {
58 
59          St2 s(200, "ace", 'M', 25, "Hangzhou");
60 
61          s.display();
62 
63          return 0;
64 
65 }

输出:

 

(2)包含子对象的派生类构造函数:

#include <iostream>

#include <string>

using namespace std;

 

class St1

{

public:

//基类构造函数,初始化成员变量

         St1(int n, string na, char se):num(n),name(na),sex(se){cout<<"St1"<<endl;}

         ~St1(){cout<<"~St1"<<endl;}

         void display1(){cout<<num<<'\t'<<name<<'\t'<<sex<<'\t'; }

protected:

         int num;

         string name;

         char sex;

};

 

class St2:public St1

{

public:

//派生类调用基类构造函数

         St2(int n, string na, char se, int n_m, string na_m, char se_m, int a, string add):St1(n,na,se),monitor(n_m,na_m,se_m)

         {age = a; addr = add;cout<<"St2"<<endl;}

         ~St2(){cout<<"~St2"<<endl;}

         void display2(){display1();cout<<age<<'\t'<<addr<<endl; }

         void showmonitor()

         {cout<<"Monitor is:"<<endl;

                   monitor.display1();

                   cout<<endl;}

private:

         int age;

         string addr;

         St1 monitor;//包含子对象

};

int main()

{

         St2 s(200, "ace", 'M', 11, "HH", 'M', 26, "Shanghai");

         s.display2();

         s.showmonitor();

         return 0;

}

 输出:

 

几点注意:

1).在调用派生类构造函数之前,系统会先调用基类的构造函数;如果派生类构造函数列表中包含对基类子对象成员的初始化(如上例中的monitor),每个基类子对象初始化时也要调用一次基类构造函数;最后才是派生类调用自身的构造函数来初始化自身新增的成员(如上例中的age,addr)。执行顺序就是派生类构造函数列表顺序:

St2(int n, string na, char se, int n_m, string na_m, char se_m, int a, string add):St1(n,na,se)[1],monitor(n_m,na_m,se_m)[2]

         {age = a; addr = add;cout<<"St2"<<endl;}[3]

2).当然,对上述三种类型进行参数初始化时,会出现以下几种特殊情况:

(a) 派生类新增成员不需要进行初始化(很常见):

St2(int n, string na, char se, int n_m, string na_m, char se_m):St1(n,na,se)[1],monitor(n_m,na_m,se_m)[2]{}       

(b)基类没有定义构造函数或者基类构造函数无参—调用基类默认构造函数

St2(int a, string add ){age = a; addr = add;cout<<"St2"<<endl;}[3]

(c) 基类中重载了构造函数,既有有参的又有无参的,具体调用哪个视派生类构造函数参数个数而定。

 

 

2.派生类的析构函数【留坑---虚析构函数】:

(1).正如派生类不能继承基类的构造函数,派生类也不能继承基类的析构函数,派生类的清理工作由派生自身析构函数负责,基类的清理工作由基类析构函数负责。

(2).析构函数的调用顺序正好和构造函数调用顺序相反,即先调用派生类析构函数清理新增的成员,再调用子对象析构函数(基类析构函数)清理子对象,最后再调用基类析构函数清理基类成员。

 

posted @ 2016-11-30 16:39  Acelit  阅读(10777)  评论(0编辑  收藏  举报