美文网首页
C++中继承的构造与析构

C++中继承的构造与析构

作者: nethanhan | 来源:发表于2017-10-14 10:55 被阅读0次

    子类对象的构造

    • 子类中可以定义构造函数
    • 子类构造函数
      • 必须对继承而来的成员进行初始化
        • 直接通过 初始化列表 或者 赋值的方式 进行初始
        • 调用父类构造函数 进行初始化
    • 父类构造函数在子类中的调用方式
      • 默认调用
        • 适用于无参构造函数和使用默认参数的构造函数
      • 显示调用
        • 通过 初始化列表 进行调用
        • 适用于所有父类构造函数
    • 父类构造函数的调用
    class Child : public Parent
    {
        public:
            //隐式调用
            Child()
            {
                cout << "Child()" << endl;
            }
            //显示调用
            Child(string s) : Parent("Parameter to Parent")
            {
                cout << "Child() : " << s << endl;
            }
    }
    

    举个例子:

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class Parent 
    {
    public:
        Parent()
        {
            cout << "Parent()" << endl;
        }
        Parent(string s)
        {
            cout << "Parent(string s) : " << s << endl;
        }
    };
    
    class Child : public Parent
    {
    public:
        //这里隐式调用了父类构造
        Child()
        {
            cout << "Child()" << endl;
        }
        //这里再初始化列表中显示的调用了父类构造
        Child(string s) : Parent(s)
        {
            cout << "Child(string s) : " << s << endl;
        }
    };
    
    int main()
    {       
        //初始化c时,调用了不带参数的父类构造
        //也调用了不带参数的子类构造
        Child c; 
    
        //初始化cc时,调用了带参数的父类构造
        //也调用了带参数的子类构造
        Child cc("cc");
        
        return 0;
    }
    

    运行结果如下:

    Parent()
    Child()
    Parent(string s) : cc
    Child(string s) : cc
    
    • 构造规则
      • 子类对象在创建时会首先调用父类的构造函数
      • 先执行父类构造函数再执行子类的构造函数
      • 父类构造函数可以被隐式调用或者显示调用
    • 对象创建时构造函数的调用顺序
      1. 调用父类的构造函数
      2. 调用成员变量的构造函数
      3. 调用类自身的构造函数
      4. 口诀: 先父母后客人再自己

    举个例子:

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class Object
    {
    public:
        Object(string s)
        {
            cout << "Object(string s) : " << s << endl;
        }
    };
    
    class Parent : public Object
    {
    public:
        Parent() : Object("Default")
        {
            cout << "Parent()" << endl;
        }
        Parent(string s) : Object(s)
        {
            cout << "Parent(string s) : " << s << endl;
        }
    };
    
    class Child : public Parent
    {
        Object mO1;
        Object mO2;
    public:
        Child() : mO1("Default 1"), mO2("Default 2")
        {
            cout << "Child()" << endl;
        }
        //这里先调用Parent(s) 父类的带参构造函数
        //再分别调用成员变量 m01 m02 的带参构造函数
        //最后调用自身的 带参构造函数
        Child(string s) : Parent(s), mO1(s + " 1"), mO2(s + " 2")
        {
            cout << "Child(string s) : " << s << endl;
        }
    };
    
    int main()
    {       
        Child cc("cc");
        
        return 0;
    }
    

    运行结果如下:

    Object(string s) : cc
    Parent(string s) : cc
    Object(string s) : cc 1
    Object(string s) : cc 2
    Child(string s) : cc
    

    子类对象的析构

    • 析构函数的调用顺序与构造函数相反
      1. 执行自身的析构函数
      2. 执行成员变量的析构函数
      3. 执行父类的析构函数

    举个例子:

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class Object
    {
        string ms;
    public:
        Object(string s)
        {
            cout << "Object(string s) : " << s << endl;
            ms = s;
        }
        ~Object()
        {
            cout << "~Object() : " << ms << endl;
        }
    };
    
    class Parent : public Object
    {
        string ms;
    public:
        Parent() : Object("Default")
        {
            cout << "Parent()" << endl;
            ms = "Default";
        }
        Parent(string s) : Object(s)
        {
            cout << "Parent(string s) : " << s << endl;
            ms = s;
        }
        ~Parent()
        {
            cout << "~Parent() : " << ms << endl;
        }
    };
    
    class Child : public Parent
    {
        Object mO1;
        Object mO2;
        string ms;
    public:
        Child() : mO1("Default 1"), mO2("Default 2")
        {
            cout << "Child()" << endl;
            ms = "Default";
        }
        Child(string s) : Parent(s), mO1(s + " 1"), mO2(s + " 2")
        {
            cout << "Child(string s) : " << s << endl;
            ms = s;
        }
        
        ~Child()
        {
            cout << "~Child() " << ms << endl;
        }
    };
    
    int main()
    {       
        //继承顺序为: Child->Parent->Object
        //然后 Child 中有两个Object成员变量
        Child cc("cc");
        
        cout << endl;
        
        //所以构造顺序为 先父母
        //1、调用Object 带参构造 调用Parent 带参构造
        //再客人
        //2、调用Object 带参构造
        //后自己
        //3、调用Child 带参构造
    
        //析构顺序正好相反 先自己
        //1、调用Child 析构
        //再客人
        //2、调用Object 析构
        //后父母
        //3、调用Parent Object 析构
        return 0;
    }
    

    执行结果如下:

    Object(string s) : cc
    Parent(string s) : cc
    Object(string s) : cc 1
    Object(string s) : cc 2
    Child(string s) : cc
    
    ~Child() cc
    ~Object() : cc 2
    ~Object() : cc 1
    ~Parent() : cc
    ~Object() : cc
    

    相关文章

      网友评论

          本文标题:C++中继承的构造与析构

          本文链接:https://www.haomeiwen.com/subject/ddsxuxtx.html