• 继承的构造和析构


    • 思考问题:如何初始化父类成员?父类构造函数和子类构造函数有什么关系呢?
    • 子类对象的构造
    1. 子类中可方式以定义构造函数
    2. 子类构造函数必须对继承而来的成员进行初始化:
                1)直接通过初始化列表或者赋值的方式进行初始化 
                2)调用父类构造函数进行初始化
    • 父类构造函数在子类中的调用方式
    1. 默认调用:适用于无参构造函数和使用默认参数的构造函数
    2. 显示调用:通过初始化列表进行调用,适用于所有父类构造函数
    3. 如果子类没有显示调用,那么在父类中需要有无参构造函数

    class Child : public Parent
    {
    public:
            //隐式调用父类中的无参构造函数
        Child()
        {
            cout << "Child()" << endl;
        }
        //显式调用父类构造函数
        Child(string _str) : Parent(_str)
        {
            name = _str;
            cout << "Child(string _str):"<< name<< endl;
        }
    };
    • 构造规则
    1. 子类对象在创建时会首先调用父类的构造函数
    2. 先执行父类构造函数再执行子类的构造函数
    3. 父类构造函数可以被隐式调用或者显式调用
    • 对象创建时构造函数的调用顺序
    1. 调用父类的构造函数
    2. 调用成员变量的构造函数
    3. 调用类自身的构造函数
    4. 口诀:先父母,后客人,再自己。
    • 实验
    // 继承的构造和析构.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
    //
    #include <iostream>
    #include <string>
    using namespace std;
    class Grandfather
    {
    public:
        Grandfather()
        {
            cout << " Grandfather()" << endl;
        }
        Grandfather(string _str)
        {
            cout << "Grandfather(string _str):" << _str << endl;
        }
    };
    class Parent :public Grandfather
    {
    protected:
        string name;
    public:
        Parent() : Grandfather("default")
        {
            cout << "Parent()" << endl;
        }
        Parent(string _str):Grandfather("Grandfather")
        {
            name = _str;
            cout << "Parent(string _str):"<<name << endl;
        }
    };
    class Child : public Parent
    {
        Grandfather guest;
    public:
        Child() : guest("default")
        {
            cout << "Child()" << endl;
        }
        //显式调用父类构造函数
        Child(string _str) : Parent("father"),guest("guest")
        {
            name = _str;
            cout << "Child(string _str):"<< name<< endl;
        }
    };
    int main()
    {
        Child chenge("son");
    }
    • 运行结果
            Grandfather(string _str):Grandfather
            Parent(string _str):father
            Grandfather(string _str):guest
            Child(string _str):son
    • 子类对象的析构
    1. 执行自身的析构函数
    2. 执行成员变量的析构函数
    3. 执行父类的析构函数
    • 实验:
     1 // 继承的构造和析构.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
     2 //
     3 #include <iostream>
     4 #include <string>
     5 using namespace std;
     6 class Grandfather
     7 {
     8     string name;
     9 public:
    10     Grandfather()
    11     {
    12         cout << " Grandfather()" << endl;
    13     }
    14     Grandfather(string _str)
    15     {
    16         name = _str;
    17         cout << "Grandfather(string _str):" << _str << endl;
    18     }
    19     ~Grandfather()
    20     {
    21         cout << "~Grandfather():" << name << endl;
    22     }
    23 };
    24 class Parent :public Grandfather
    25 {
    26     string name;
    27 public:
    28     Parent() : Grandfather("default")
    29     {
    30         name = "default";
    31         cout << "Parent()" << endl;
    32     }
    33     Parent(string _str):Grandfather("Grandfather")
    34     {
    35         name = _str;
    36         cout << "Parent(string _str):"<<name << endl;
    37     }
    38     ~Parent()
    39     {
    40         cout << "~Parent():" << name << endl;
    41     }
    42 };
    43 class Child : public Parent
    44 {
    45     string name;
    46     Grandfather guest;
    47 public:
    48     Child() : guest("default")
    49     {
    50         name = "default";
    51         cout << "Child()" << endl;
    52     }
    53     //显式调用父类构造函数
    54     Child(string _str) : Parent("father"),guest("guest")
    55     {
    56         name = _str;
    57         cout << "Child(string _str):"<< name<< endl;
    58     }
    59     ~Child()
    60     {
    61         cout << "~Child():" << name << endl;
    62     }
    63 };
    64 int main()
    65 {
    66     Child chenge("son");
    67 }
    • 运行结果
                Grandfather(string _str):Grandfather
                Parent(string _str):father
                Grandfather(string _str):guest
                Child(string _str):son
                ~Child():son
                ~Grandfather():guest
                ~Parent():father
                ~Grandfather():Grandfather
    • 小结
    1. 子类对象在创建时需要调用父类构造函数进行初始化
    2. 先执行父类构造函数然后执行成员的构造函数
    3. 父类构造函数显式调用需要在初始化列表中进行
    4. 子类对象在销毁时需要调用父类析构函数进行清理
    5. 析构顺序与构造顺序对称相反
     
    主要记录的是学习听课的笔记
  • 相关阅读:
    P1443 马的遍历
    P1747 好奇怪的游戏
    蜀绣
    Five hundred miles
    如果没有你
    Yellow
    流星

    深入理解计算机中的 csapp,h和csapp.c
    可迭代的集合类型使用foreach语句
  • 原文地址:https://www.cnblogs.com/chengeputongren/p/12243105.html
Copyright © 2020-2023  润新知