博客
关于我
C++ 多态的原理
阅读量:794 次
发布时间:2019-03-24

本文共 1009 字,大约阅读时间需要 3 分钟。

多态(Polymorphism)是面向对象编程中一个核心概念,用于解决抽象编程的问题。它使得程序能够在不关心具体对象类型的情况下,正确调用方法。以下是关于多态的详细解析:

  • 多态的作用

    多态的主要目的是让程序能够处理不同类型的对象,而无需关心这些对象的具体类型。通过多态,程序可以在运行时根据对象的类型动态决定如何处理,这极大地提高了程序的灵活性和扩展性。

  • 多态的实现机制

    在C++中,多态的实现依赖于虚方法(Virtual Method)。要实现多态,必须满足两个条件:

    • 表面类型(即显示的类型)与实际类型(真实类型)不同。
    • 方法是通过虚方法来实现的。
    1. 多态的实现原理
      多态的核心机制在于通过指针或引用来指向对象,而这些对象在内存中包含一个虚方法表指针。无论是父类对象还是子类对象,这个虚方法表指针的位置都是一样的。虚方法表本身是一个数组,存储了各种方法的地址。
      • 当子类继承父类时,子类会复制父类的虚方法表。
      • 对于重写的虚方法,子类会替换父类的方法指针,确保调用的是子类特定版本的方法。
      • 对于新增的虚方法,会添加到虚方法表的末尾。
      1. 多态的实际表现
        通过一个常见的例子来理解多态:考虑如下代码:
      2. Animal* pa = new Dog();  
        pa->Say();

        在编译阶段,这条代码会被翻译为:

        pa->pFunArray[0]()

        这里的pFunArray是虚方法表指针,pFunArray[0]对应的是Animal类的第一个虚方法。当子类(Dog)继承父类(Animal)时,Dog会替换父类的虚方法表,确保调用的是子类特定的方法。

        1. 多态的局限性
          尽管多态非常有用,但它也存在一些缺陷。
          • 内存浪费:子类需要复制父类的虚方法表,且只对重写的方法进行替换。因此,如果父类有1000个虚方法,而子类只重写了一个,剩下的999个方法都会有两个副本,导致内存占用增加。
          • 性能开销:当类继承层次深,且类的数量多时,虚方法表的复制和管理会对性能产生负面影响。
          1. 解决多态问题的方法
            为了缓解多态的内存和性能问题,可以采用以下策略:
            • 只保存重写的虚方法:对于没有重写的方法,直接引用父类的虚方法表。
            • 使用哈希表优化:通过哈希表记录每个虚方法的实际调用地址,避免重复存储未重写的方法,从而减少内存占用。这种方法类似于现代C++中的std::visit功能。

            通过以上机制,多态能够在保证程序灵活性的同时,尽量减少内存和性能的开销。

    转载地址:http://loyuk.baihongyu.com/

    你可能感兴趣的文章
    MySQL Xtrabackup 安装、备份、恢复
    查看>>
    mysql [Err] 1436 - Thread stack overrun: 129464 bytes used of a 286720 byte stack, and 160000 bytes
    查看>>
    MySQL _ MySQL常用操作
    查看>>
    MySQL – 导出数据成csv
    查看>>
    MySQL —— 在CentOS9下安装MySQL
    查看>>
    MySQL —— 视图
    查看>>
    mysql 不区分大小写
    查看>>
    mysql 两列互转
    查看>>
    MySQL 中开启二进制日志(Binlog)
    查看>>
    MySQL 中文问题
    查看>>
    MySQL 中日志的面试题总结
    查看>>
    mysql 中的all,5分钟了解MySQL5.7中union all用法的黑科技
    查看>>
    MySQL 中的外键检查设置:SET FOREIGN_KEY_CHECKS = 1
    查看>>
    Mysql 中的日期时间字符串查询
    查看>>
    mysql 中索引的问题
    查看>>
    MySQL 中锁的面试题总结
    查看>>
    MySQL 中随机抽样:order by rand limit 的替代方案
    查看>>
    MySQL 为什么需要两阶段提交?
    查看>>
    mysql 为某个字段的值加前缀、去掉前缀
    查看>>
    mysql 主从
    查看>>