实用经验 80 理解派生类构造/析构运行原理

对象的构造和析构扮演着对象创建和释放的角色。如同现实世界中的其他事物一样,对象同样有自己的创建顺序和释放流程,尤其在存在继承和虚继承的对象体系中,对象的构造和析构更显得尤为重要。

此处以人和学生单继承关系为例进行说明。

// 人数据类型
class CPerson
{
public:
     CPerson() 
     {
          m_pszName = NULL;
          cout << “Create CPerson” <<endl;
     }
     ~CPerson() 
     {
          m_pszName = NULL;
          cout << “Delete CPerson” <<endl;
     }
     // 获得人的名称
     char *GetName()
     {
          return m_pszName;
     }
     // 设置人的名称
     void  SetName(char *pszName)
     {
          m_pszName = pszName;
     }
private:
     char *m_pszName;
};

//  学生类
class CStudent: public CPerson
{
public:
     CStudent () 
     {
          m_pszSchoolName = NULL;
          cout << “Create CStudent” <<endl;
     }
     ~ CStudent () 
     {
          m_pszSchoolName = NULL;
          cout << “Delete CStudent” <<endl;
     }
     char *GetSchool()
     {
          return m_pszSchoolName;
     }
     void  SetSchool(char *pszSchool)
     {
          m_pszSchoolName = pszSchool;
     }
private:
     char *m_pszSchoolName;
};

int main(void)
{
    CStudent Xiaoming;
    return 0;
} 

这段代码的运行结果如下:

Create CPerson
Create CStudent
Delete CStudent
Delete CPerson

从运行结果可得如下的结论:1. 单继承类在构造时,先是构造基类。然后才进行自身的构造;2. 基类依然存在上层基类,则先进行上层基类的构造。然后在构造基类本身;3. 析构的顺序是构造执行顺序的严格逆序

单继承构造析构运行原理

  • 单继承类在进行对象构造时,总是从类的最根处开始,由深及浅,先基类后子类,层层构造,这个顺序不能改变。
  • 单继承类对象在析构时,析构函数的执行顺序是构造顺序的严格逆序。

多继承是C++为了更贴近自然而支持的一种继承机制。多继承比单继承更加复杂。

// 输入文件接口
class CInFile
{
public:
   CInFile() 
   {
    cout << “Create CInFile class<< endl;
   }
   virtual ~ CInFile()
   {
    cout << “Delete CInFile class<< endl;
   }
};

// 输出文件接口实现
class COutFile
{
public:
   COutFile() 
   {
      cout << “Create COutFile” << endl;
   }
   virtual ~COutFile()
   {
     Cout << “ Delete COutFile” << endl;
   }
};

// 输入输出文件接口
class CIOFile : public CInFile, public COutFile
{
public:
   CIOFile () 
   {
      cout << “Create CIOFile” << endl;
   }
   ~CIOFile()
   {
      Cout << “ Delete CIOFile” << endl;
   }
};

int main(void)
{
    CIOFile  MyFile;
    return 0;
}

这段代码的运行结果为:

Create CInFile class
Create COutFile
Create CIOFile
Delete CIOFile
Delete COutFile
Delete CInFile class

从上述运行结果可得如下的结论:1. 多继承继承类在构造,先构造的是它的所有基类,同时这些基类构造的顺序和其声明的顺序要一致。然后才进行自身的构造。2. 基类依然存在上层基类,则先进行上层基类的构造(如果上层基类同样也是多继承,则分别构造其所有基类),然后在构造基类;3. 析构的顺序和构造执行的顺序是严格按照构造顺序的逆序执行。

多继承构造析构运行原理

  • 多继承类在进行对象构造,从类的最根处开始,由深及浅,先基类后子类(其中基类的构造顺序按照声明的顺序由前及后),层层构造,这个顺序不能改变。
  • 多继承类对象在析构时,析构函数的执行顺序是构造顺序的严格逆序。

单继承和多继承的构造和析构执行顺序一般容易掌握,当一个类中包含成员类对象时,此时的构造和析构顺序一般也很容易混淆。看这段代码所展示的包含成员类对象的构造顺序。

// 人数据类型
class CPerson
{
public:
    CPerson() 
    {
        cout << "Create CPerson" <<endl;
    }
    ~CPerson() 
    {
        cout << "Delete CPerson"<<endl;
    }
};

//  学生类
class CStuden
{
public:
    CStudent () 
    {;
        cout << "Create CStudent" <<endl;
    }
    ~ CStudent () 
    {
        cout << "Delete CStudent" <<endl;
    }
};
// 学校类实现
class CSchool
{  
public:
    CSchool ()
    {
        cout << "Create CScholl" << endl;
    }
    ~CSchool()
    {
        cout << "Delete CScholl" << endl;
    }

private:
    CStudent  m_student;
 	CPerson   m_Teacher;
};

int main(void)
{
    CSchool MySchool;
    return 0;
} 

这段代码的运行结果为:

Create CStudent
Create CPerson
Create CScholl
Delete CScholl
Delete CPerson
Delete CStudent

由此可见,成员类对象先被构造,而且成员对象构造的顺序与成员对象声明的顺序严格一致,当析构时成员对象先被析构,而且析构的顺序是声明顺序的严格逆序。

总结

综上讨论,可以得到这样的结论:

  • 派生类构造,先构造所有基类(基类构造的顺序为其声明的顺序),然后才构造当前派生类;
  • 派生类如存在成员对象,成员对象会先被构造,然后才运行构造函数构造当前派生类;

请谨记

  • 派生类构造,先构造所有基类(基类构造的顺序为其声明的顺序),然后才构造当前派生类
  • 派生类如存在成员对象,成员对象会先被构造,然后才运行构造函数构造当前派生类
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值