zoukankan      html  css  js  c++  java
  • 33 继承中的构造和析构

    1 问题

    • 创建子类对象时如何初始化父类成员?父类构造函数和子类构造函数有什么关系?

    2 子类对象的构造

    • 子类中可以定义构造函数

    • 子类构造函数

      • 必须对继承而来的成员进行初始化
        • 直接通过初始化列表或者赋值的方式进行初始:这种方式对于子类不能访问的父类成员不起作用,必须使用其他方法(调用父类构造函数)
        • 调用父类构造函数进行初始化
    • 父类构造函数在子类中的调用方式

      • 隐式调用(默认调用)
        • 只适用于无参构造函数使用默认参数的构造函数
      • 显式调用
        • 只能通过初始化列表进行调用
        • 适用于所有父类构造函数
    • 父类构造函数的调用

      class Child : public Parent
      {
      public:
          Child()  //隐式调用:父类无参构造函数
          {
              cout << "Child()" << endl;
          }
          Child(string s)  //显式调用:父类有参构造函数
              : Parent("Parameter to Parent")
          {
              cout << "Child() : " << s << endl;
          }
      };
      
    • 示例1:子类的构造函数1

      • Demo1:隐式调用父类无参构造函数,显式调用父类有参构造函数

        #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()
        {       
            Child c; 
            Child cc("cc");
            
            return 0;
        }
        
      • 编译运行

        Parent()
        Child()
        Parent(string s) : cc
        Child(string s) : cc
        
      • Demo2:验证隐式调用父类无参构造函数

        #include <iostream>
        #include <string>
        
        using namespace std;
        
        class Parent 
        {
        public:
            Parent(string s)
            {
                cout << "Parent(string s) : " << s << endl;
            }
        };
        
        class Child : public Parent
        {
        public:
            Child()
            {
                cout << "Child()" << endl;
            }
            Child(string s)
            {
                cout << "Child(string s) : " << s << endl;
            }
        };
        
        int main()
        {       
            Child c;  //error
            
            return 0;
        }
        
      • 编译

        test.cpp: In constructor ‘Child::Child()’:
        test.cpp:19: error: no matching function for call to ‘Parent::Parent()’
        test.cpp:9: note: candidates are: Parent::Parent(std::string)
        test.cpp:7: note:                 Parent::Parent(const Parent&)
        test.cpp: In constructor ‘Child::Child(std::string)’:
        test.cpp:23: error: no matching function for call to ‘Parent::Parent()’
        test.cpp:9: note: candidates are: Parent::Parent(std::string)
        test.cpp:7: note:                 Parent::Parent(const Parent&)
        
      • Demo3:验证隐式调用父类无参构造函数

        #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)
            {
                cout << "Child(string s) : " << s << endl;
            }
        };
        
        int main()
        {       
            Child c; 
            Child cc("cc");
            
            return 0;
        }
        
      • 编译运行

        Parent()
        Child()
        Parent()
        Child(string s) : cc
        
    • 构造规则

      • 子类对象在创建时会首先调用父类的构造函数
      • 先执行父类构造函数,再执行子类的构造函数
      • 父类构造函数可以被隐式调用或者显式调用
    • 对象创建时构造函数的调用顺序

      • 1.调用父类的构造函数
      • 2.调用成员变量的构造函数
      • 3.调用类自身的构造函数
    • 示例2:子类的构造函数2

      • Demo

        #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;
            }
            //先父类,再成员变量
            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
        

    3 子类对象的析构

    • 析构函数的调用顺序与构造函数相反

      • 1.执行自身的析构函数
      • 2.执行成员变量的析构函数
      • 3.执行父类的析构函数
    • 示例:对象的析构

      • Demo

        #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 cc("cc");
            
            cout << endl;
            
            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
        
  • 相关阅读:
    GridView编辑删除操作
    hdu 4857 逃生 拓扑排序+PQ,剥层分析
    每日回顾Shell —cat,tail,head
    uva:10700
    Unity多玩家网络游戏开发教程1章Unity带有网络功能
    android com.handmark.pulltorefresh 使用技巧
    Jsoup 抓取和数据页 认识HTTP头
    JDK8在Java转让Javascript脚本引擎动态地定义和运行代码
    2013-2014约半学期的学习和规划研究综述
    Javascript 设计模式 辛格尔顿
  • 原文地址:https://www.cnblogs.com/bky-hbq/p/13903902.html
Copyright © 2011-2022 走看看