当前位置: 首页 > news >正文

C++多态的实现原理

静态多态(编译期)

函数重载

  • 允许在同一个作用域中声明多个功能类似的同名函数
  • 函数的参数列表不同(参数个数,参数类型,参数顺序)
  • 注意:不能通过函数返回值区分(name mangling不包括返回值)

原理

  • 预编译:头文件的函数声明拷贝到源文件,避免编译过程找不到函数定义
  • 编译:语法分析,同时进行符号汇总(函数名)
  • 汇编:生成函数名到函数地址的映射,方便之后通过函数名找到函数定义的位置
  • 链接:将多个文件的符号表汇总合并

*objdump -t o

  • _ZN + 类长度+ 类名+ 函数名长度 + 函数名 + E + 类型首字母

模版

  • 编译期间进行实例化
  • 性能要高,避免了运行时的开销

动态多态

虚函数重写,运行时确定

  • 在基类的函数前面加上virtual关键字,派生类重写函数
  • 运行时根据对象的类型调用相应的函数
  • 如果对象的类型是基类,则调用基类的函数
  • 如果对象的类型是派生类,调用派生类的函数

原理

  • 早绑定:编译时已经确定函数调用的地址
  • 晚绑定:需要用到虚函数表,运行时才能确定

早绑定(Early Binding)

早绑定,也称为静态绑定(Static Binding),是在编译时确定函数调用的具体实现。这意味着在编译阶段,编译器已经知道函数调用对应的具体函数。早绑定通常与非虚函数、函数重载和模板有关。

早绑定的优点:

  1. 性能高,因为函数调用在编译时已确定,不需要运行时查找。
  2. 类型安全,因为编译器在编译时进行类型检查,可以捕捉到类型不匹配的错误。

示例:

#include <iostream>
using namespace std;class Base {
public:void display() {cout << "Base display" << endl;}
};class Derived : public Base {
public:void display() {cout << "Derived display" << endl;}
};int main() {Base b;Derived d;Base *ptr = &d;ptr->display(); // 调用 Base::display()return 0;
}

在上述示例中,ptr->display() 是早绑定,因为编译器在编译时已经知道 ptrBase 类型的指针,并且调用 Base 类的 display 函数。

晚绑定(Late Binding)

晚绑定,也称为动态绑定(Dynamic Binding),是在运行时确定函数调用的具体实现。这通常通过虚函数(virtual functions)和多态性实现。晚绑定依赖于虚函数表(vtable),通过指针在运行时查找函数的具体实现。

晚绑定的优点:

  1. 灵活性高,允许程序在运行时决定调用哪个函数。
  2. 支持多态性,使得可以通过基类指针调用派生类的实现。

示例:

#include <iostream>
using namespace std;class Base {
public:virtual void display() {cout << "Base display" << endl;}
};class Derived : public Base {
public:void display() override {cout << "Derived display" << endl;}
};int main() {Base *ptr = new Derived();ptr->display(); // 调用 Derived::display()delete ptr;return 0;
}

在上述示例中,ptr->display() 是晚绑定,因为 display 是虚函数,具体调用的函数是在运行时根据对象的实际类型(即 Derived)决定的。

最后给大家推荐一个LinuxC/C++高级架构系统教程的学习资源与课程,可以帮助你有方向、更细致地学习C/C++后端开发,具体内容请见 https://xxetb.xetslk.com/s/1o04uB

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • python 代码设计贪吃蛇
  • python如何查看类的函数
  • C++学习笔记
  • 自动化回复信息工具的开发分享!
  • 报错:pytest: error: argument -m: expected one argument (via addopts config)
  • 100 个网络基础知识普及,看完成半个网络高手!
  • 程序的控制结构——if-else语句(双分支结构)【互三互三】
  • 语言模型演进:从NLP到LLM的跨越之旅
  • 【C++航海王:追寻罗杰的编程之路】一篇文章带你认识哈希
  • 面向对象进阶基础练习
  • 逆序对——树状数组
  • 爬虫-浏览器自动化
  • OceanBase 配置项系统变量实现及应用详解(1):配置项的定义及使用方法
  • 超级好用的java http请求工具
  • shift 命令学习
  • Babel配置的不完全指南
  • CentOS6 编译安装 redis-3.2.3
  • CSS相对定位
  • input的行数自动增减
  • java8-模拟hadoop
  • Spark in action on Kubernetes - Playground搭建与架构浅析
  • 对话:中国为什么有前途/ 写给中国的经济学
  • 仿天猫超市收藏抛物线动画工具库
  • 好的网址,关于.net 4.0 ,vs 2010
  • 离散点最小(凸)包围边界查找
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 如何设计一个微型分布式架构?
  • 使用 5W1H 写出高可读的 Git Commit Message
  • 树莓派 - 使用须知
  • 算法-图和图算法
  • 系统认识JavaScript正则表达式
  • 想写好前端,先练好内功
  • 用Python写一份独特的元宵节祝福
  • ​ 轻量应用服务器:亚马逊云科技打造全球领先的云计算解决方案
  • ​一文看懂数据清洗:缺失值、异常值和重复值的处理
  • #Java第九次作业--输入输出流和文件操作
  • #数据结构 笔记三
  • #我与Java虚拟机的故事#连载14:挑战高薪面试必看
  • $(function(){})与(function($){....})(jQuery)的区别
  • (02)Cartographer源码无死角解析-(03) 新数据运行与地图保存、加载地图启动仅定位模式
  • (AtCoder Beginner Contest 340) -- F - S = 1 -- 题解
  • (c语言)strcpy函数用法
  • (floyd+补集) poj 3275
  • (ros//EnvironmentVariables)ros环境变量
  • (二刷)代码随想录第16天|104.二叉树的最大深度 559.n叉树的最大深度● 111.二叉树的最小深度● 222.完全二叉树的节点个数
  • (翻译)Entity Framework技巧系列之七 - Tip 26 – 28
  • (附源码)ssm智慧社区管理系统 毕业设计 101635
  • (剑指Offer)面试题34:丑数
  • (七)c52学习之旅-中断
  • (十八)用JAVA编写MP3解码器——迷你播放器
  • (一)Spring Cloud 直击微服务作用、架构应用、hystrix降级
  • (转)linux下的时间函数使用
  • (转)MVC3 类型“System.Web.Mvc.ModelClientValidationRule”同时存在
  • .Net Attribute详解(上)-Attribute本质以及一个简单示例
  • .net core 使用js,.net core 使用javascript,在.net core项目中怎么使用javascript