• 【C++】继承 ⑥ ( 类型兼容性原则 | 父类指针 指向 子类对象 | 使用 子类对象 为 父类对象 进行初始化 )







    一、public 公有继承 - 示例分析




    1、类型兼容性原则


    类型兼容性原则 : C++ 的 " 类型兼容性原则 “ 又称为 ” 赋值兼容性原则 " ;

    子类代替父类 : 需要 基类 ( 父类 ) 对象的 地方 , 都可以使用 " 公有继承 " 的 派生类 ( 子类 ) 对象 替代 , 该 派生类 ( 子类 ) 得到了 除 构造函数 和 析构函数 之外的 所有 成员变量 和 成员方法 ;

    功能完整性 : " 公有继承 " 的 派生类 ( 子类 ) 本质上 具有 基类 ( 父类 ) 的 完整功能 , 使用 基类 可以解决的问题 , 使用 公有继承派生类 都能解决 ;


    特别注意 : " 保护继承 " 和 " 私有继承 " 的 派生类 , 是 不具有 基类 的 完整功能的 , 因为 最终继承 后的派生类 , 无法在 类外部调用 父类的 公有成员 和 保护成员 ;


    2、类型兼容性原则应用场景


    " 类型兼容性原则 " 应用场景 :

    • 直接使用 : 使用 子类对象 作为 父类对象 使用 ;
    • 赋值 : 将 子类对象 赋值给 父类对象 ;
    • 初始化 : 使用 子类对象 为 父类对象 初始化 ;
    • 指针 : 父类指针 指向 子类对象 , 父类指针 值为 子类对象 在 堆内存 的地址 , 也就是 将 子类对象 地址 赋值给 父类类型指针 ;
    • 引用 : 父类引用 引用 子类对象 , 将 子类对象 赋值给 父类类型的引用 ;




    二、类型兼容性原则 - 示例分析



    定义父类 Parent , 子类 Child ;

    class Parent {
    public:
        void funParent()
        {
            cout << "父类 funParent 函数" << endl;
        }
    
    private:
        int c;
    };
    
    // 子类 公有继承 父类
    class Child : public Parent {
    public:
        void funChild() 
        {
            cout << "子类 funChild 函数" << endl;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    1、父类指针 指向 子类对象


    定义 一个子类对象 Child child ;

    定义父类的指针 , 将 指针 指向 子类对象 的地址 , 这是合法的 ;

    代码示例 :

        // 父类对象
        Parent parent;
        // 子类对象
        Child child;
    
        // I. 类型兼容性原则 : 父类指针 指向 子类对象
        Parent* p_parent2 = NULL;
        p_parent2 = &child;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    该原则的应用场景如下 : 定义函数 , 接收 父类指针 或 父类引用 , 此处可以直接传入 子类指针 或 子类引用 ;

    // 函数接收父类指针类型
    // 此处可以传入子类对象的指针
    void fun_pointer(Parent* obj)
    {
        obj->funParent();
    }
    
    // 函数接收父类引用类型
    // 此处可以传入子类对象的引用
    void fun_reference(Parent& obj)
    {
        obj.funParent();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2、使用 子类对象 为 父类对象 进行初始化


    定义父类对象 , 可以直接使用 子类对象 进行初始化操作 ;

        // II. 类型兼容性原则 : 使用 子类对象 为 父类对象 进行初始化
        Parent parent = child;
    
    • 1
    • 2

    3、完整代码示例


    #include "iostream"
    using namespace std;
    
    class Parent {
    public:
        void funParent()
        {
            cout << "父类 funParent 函数" << endl;
        }
    
    private:
        int c;
    };
    
    // 子类 公有继承 父类
    class Child : public Parent {
    public:
        void funChild() 
        {
            cout << "子类 funChild 函数" << endl;
        }
    };
    
    // 函数接收父类指针类型
    // 此处可以传入子类对象的指针
    void fun_pointer(Parent* obj)
    {
        obj->funParent();
    }
    
    // 函数接收父类引用类型
    // 此处可以传入子类对象的引用
    void fun_reference(Parent& obj)
    {
        obj.funParent();
    }
    
    int main() {
    
        // 父类对象
        Parent parent;
        // 子类对象
        Child child;
    
    
        // 父类对象 可以调用 父类公有函数
        parent.funParent();
        // 子类对象 可以调用 子类自身公有函数
        child.funChild();
        // 子类对象 可以调用 父类公有函数
        child.funParent();
    
        // 将指向子类对象的指针传给接收父类指针的函数
        // 也是可以的
        fun_pointer(&child);
    
        // 接收父类引用 , 此处传入子类引用
        fun_reference(child);
    
    
        // 赋值兼容性原则 : 
        cout << "\n赋值兼容性原则示例 : \n" << endl;
    
    
        // 常规操作 : 父类指针 指向 父类对象
        Parent* p_parent = NULL;
        p_parent = &parent;
        // 通过父类指针调用父类函数
        p_parent->funParent();
    
        // 将指向子类对象的指针传给接收父类指针的函数
        // 也是可以的
        fun_pointer(p_parent);
    
        // 接收父类引用参数
        fun_reference(*p_parent);
    
    
        // I. 类型兼容性原则 : 父类指针 指向 子类对象
        Parent* p_parent2 = NULL;
        p_parent2 = &child;
        // 通过父类指针调用父类函数
        p_parent2->funParent();
    
    
        // II. 类型兼容性原则 : 使用 子类对象 为 父类对象 进行初始化
        Parent parent3 = child;
        
        
    
    	// 控制台暂停 , 按任意键继续向后执行
    	system("pause");
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95

    执行结果 :

    父类 funParent 函数
    子类 funChild 函数
    父类 funParent 函数
    父类 funParent 函数
    父类 funParent 函数
    
    赋值兼容性原则示例 :
    
    父类 funParent 函数
    父类 funParent 函数
    父类 funParent 函数
    父类 funParent 函数
    Press any key to continue . . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述

  • 相关阅读:
    关于【eolinker4.0开源】API文档功能和API测试功能的搭建、搭建API文档、简单使用自动化测试
    数据资产“入表”是不是红利?国企怎么认识?怎么利用?
    永州植物细胞实验室建设布局方案
    【SVM分类】基于鸽群算法优化支持向量机SVM实现分类附matlab的代码
    Logstash与FileBeat详解以及ELK整合详解
    弘辽科技:拼多多推广被限制有什么办法解除吗?有何原因?
    【Qt】对话框QDialog
    灵活多样认证授权,零开发投入保障 IoT 安全
    java 字节流写入文件内容实现换行
    Selenium元素定位神器工具谷歌浏览器插件-SelectorsHub介绍、安装和使用
  • 原文地址:https://blog.csdn.net/han1202012/article/details/133922626