C++ 多态原理深入理解

多态

引言

多态(Polymorphism)是面向对象程序设计的核心特性,指同一接口,多种实现。C++中的多态主要分为两类:

  1. 编译时多态(静态多态)
    • 通过函数重载模板实现
    • 函数调用在编译期确定(早期绑定/静态联编
    • 基于参数类型或个数区分同名函数
  2. 运行时多态(动态多态)
    • 通过继承虚函数实现
    • 函数调用在运行期确定(晚绑定/动态联编
    • 根据对象的实际类型调用对应函数

静态多态

函数重载

函数重载允许在同一作用域中声明多个同名函数,但这些函数的参数列表必须不同。

参数列表不同的具体体现:

  • 参数个数不同
  • 参数类型不同
  • 参数顺序不同

注意: 不能仅通过返回值类型来区分重载函数。

实现原理

C++通过函数名修饰机制支持函数重载,而C语言不支持此特性。

编译过程概述:

  • 预编译:将头文件中的函数声明拷贝到源文件中,避免编译时找不到函数定义。
  • 编译:进行语法分析,并符号汇总,生成符号表。
  • 汇编:生成函数名到函数地址的映射,便于后续调用时定位函数定义位置。
  • 链接:将多个目标文件的符号表汇总合并。

函数名修饰的核心流程:

  • 编译和汇编阶段,编译器根据函数名、参数类型等信息对函数名进行修饰,生成唯一的符号名
  • 不同参数列表的同名函数会被修饰成不同的符号,从而在符号表中区分。
  • 示例(GCC编译器):
    • int sum(int a, int b)_Z3sumii
    • double sum(double a, double b)_Z3sumdd
  • 修饰规则通常包含:
    • 前缀(如_Z
    • 函数名长度 + 函数名
    • 参数类型首字母(int→i, double→d, 类类型→类名等)

模板

模板(template)是 C++ 实现静态多态(编译时多态)的核心机制之一。
其本质是编译器根据模板参数在编译期生成具体代码,从而实现“同一套代码逻辑,适配多种不同类型”的多态行为。

核心原理

模板不是代码,而是代码生成器

  • 函数模板类模板 本身不会被编译成任何可直接执行的代码
  • 它只是一个蓝图,告诉编译器:当遇到对特定模板参数的使用时,请按此蓝图生成一份具体的代码

模板实例化

  • 当程序使用模板并提供具体类型参数时,编译器会执行模板实例化
  • 实例化过程:
    1. 模板参数推导:根据函数实参或显式指定的类型,确定模板参数 T 的具体类型。
    2. 模板代码替换:将模板定义中所有 T 替换为实际类型,生成一份完整的普通函数或普通类
    3. 编译生成的代码:对生成的普通代码执行常规编译。
编译期绑定
  • 同一模板函数,为不同模板参数实例化出的多个函数,拥有完全不同的函数签名和函数地址
  • 调用时,编译器通过重载决议模板参数匹配静态地选择调用哪个实例化版本。
  • 所有决策在编译期完成,无运行时开销
示例
template<typenameT> T max(T a, T b){return a > b ? a : b;}intmain(){int i =max(3,5);// (1) 实例化为 int max(int, int)double d =max(3.14,2.71);// (2) 实例化为 double max(double, double)char c =max('a','z');// (3) 实例化为 char max(char, char)}

编译器实际生成的代码(概念性):

intmax_int(int a,int b){return a > b ? a : b;}doublemax_double(double a,double b){return a > b ? a : b;}charmax_char(char a,char b){return a > b ? a : b;}

多态体现:同一 max 名称,对三种不同类型生成三个不同函数,调用时根据参数类型静态绑定到对应版本。

运行时多态

虚函数相关

用关键字 virtual 修饰的非静态成员函数称为虚函数。一旦基类将某个函数声明为 virtual,所有派生类中与该函数同名、同参数列表、同返回值的函数自动成为虚函数

派生类重新定义基类的虚函数称为重写(override)
作用:通过基类指针或引用调用该函数时,实际执行的是对象所属派生类的版本。

纯虚函数:在虚函数声明末尾添加 = 0,如:

virtualvoidbreathe()=0;

纯虚函数表示该函数在当前类中没有实现,要求派生类必须提供实现。

注:纯虚函数也可以提供函数体,但需要定义在类外;通常仅用于特殊场景(如析构函数)。

静态绑定与动态绑定

静态绑定(早绑定)
  • 编译阶段就确定了函数调用的目标地址。
  • 依据指针/引用的静态类型决定调用哪个函数。
  • 例(无虚函数)
classAnimal{public:voidbreathe(){ cout <<"animal breathe"<< endl;}};classFish:publicAnimal{public:voidbreathe(){ cout <<"fish bubble"<< endl;}}; Fish fh; Animal* p =&fh;// 静态类型为 Animal* p->breathe();// 输出 "animal breathe"

原因p 被声明为 Animal*,编译器按此类型直接绑定 Animal::breathe()

动态绑定(晚绑定)
  • 运行阶段根据对象的实际类型动态决定调用的函数。
  • 要求:通过基类指针或引用调用虚函数
  • 例(有虚函数)
classAnimal{public:virtualvoidbreathe(){ cout <<"animal breathe"<< endl;}};classFish:publicAnimal{public:voidbreathe()override{ cout <<"fish bubble"<< endl;}}; Fish fh; Animal* p =&fh;// 静态类型 Animal*,实际指向 Fish 对象 p->breathe();// 输出 "fish bubble"
动态绑定原理

虚函数表(vtable)与虚指针(vptr)
动态绑定的底层依赖虚函数表(Virtual Table)虚指针(Virtual Pointer)

虚函数表(vtable)
  • 每个包含虚函数的类(或从包含虚函数的类派生的类)都有一个虚函数表。
  • 本质:一个一维数组,按声明顺序存放该类所有虚函数的地址(包括继承自基类的虚函数和自身新增的虚函数)。
  • 继承时的虚表内容
    • 若派生类重写了基类的虚函数,则虚表中对应位置的地址替换为派生类函数地址
    • 若派生类新增虚函数,则将其地址添加在虚表末尾。
    • 若派生类未重写基类虚函数,则虚表中保存基类该函数的地址
虚指针(vptr)
  • 每个含有虚函数的类的对象中,编译器会隐式插入一个指针,称为 vptr
  • vptr 指向该对象所属类的虚函数表
  • 同一类的所有对象共享同一个虚表,但每个对象拥有自己独立的 vptr(指向同一虚表)。
[!NOTE] [[为什么每个对象拥有自己独立的 vptr ?]]

参考文章:

https://blog.ZEEKLOG.net/pzhw520hchy/article/details/51850289?fromshare=blogdetail&sharetype=blogdetail&sharerId=51850289&sharerefer=PC&sharesource=qq_60536076&sharefrom=from_link

Read more

Qwen-Image-2512 V2版 - 细节拉满,更真实的AI绘画体验 ComfyUI+WebUI 一键整合包下载

Qwen-Image-2512 V2版 - 细节拉满,更真实的AI绘画体验 ComfyUI+WebUI 一键整合包下载

Qwen-Image-2512 是 Qwen-Image 文生图基础模型的 12 月更新版本,这是一个最新的文本生成图像模型,特点是 画面更真实、细节更精致,提升了人物与自然细节的真实感,适合在创意设计、教育展示、内容生产等领域使用。 今天分享的 Qwen-Image-2512 V2版 一键包基于阿里最新开源的 Qwen-Image-2512 的FP8量化版(同时支持BF16),支持消费级显卡最低12G显存流畅运行,支持更适合小白操作的WebUI模式和专业选手的ComfyUI两种模式。 相比较上个版本,V2版因使用精度更高的FP8模型,所以在生成效果上更好,同时对硬件的要求也更高,大家根据需要选择适合自己的版本。 下载地址:点此下载   模型特点 更真实的人物表现:相比旧版本,人物的面部细节、表情和环境都更自然,不再有明显的“AI感”。   更精细的自然细节:风景、动物毛发、水流等元素渲染更逼真,层次感更强。   更准确的文字渲染:在生成带文字的图像(如海报、PPT)时,排版和字体更清晰,图文融合更好。   更强的整体性能:

Llama Factory微调深度解析:模型架构与调优原理

Llama Factory微调深度解析:模型架构与调优原理 作为一名AI研究者,当你想要深入理解Llama模型的工作原理并进行高效微调时,Llama Factory无疑是一个强大的工具。本文将带你从模型架构到调优原理,逐步解析Llama Factory的核心机制,帮助你在实际项目中更好地应用这一框架。 Llama Factory简介与核心价值 Llama Factory是一个专为Llama系列模型设计的微调框架,它简化了模型微调的流程,同时提供了丰富的配置选项。通过Llama Factory,你可以: * 快速加载预训练的Llama模型 * 灵活配置微调参数 * 支持多种数据格式(如Alpaca、ShareGPT等) * 提供对话模板管理功能 * 支持模型导出和部署 这类任务通常需要GPU环境,目前ZEEKLOG算力平台提供了包含该镜像的预置环境,可快速部署验证。 Llama模型架构解析 Transformer基础结构 Llama模型基于Transformer架构,主要包含以下组件: 1. 多头自注意力机制(Multi-Head Self-Attent

硕士论文盲审前降AI率:盲审评委到底会不会看AIGC报告?

硕士论文盲审前降AI率:盲审评委到底会不会看AIGC报告? 最近收到不少同学私信问我:"学长,我硕士论文马上要送盲审了,学校说要做AIGC检测,但盲审评委真的会看这个报告吗?"说实话,这个问题我当初也纠结过。今天就把我了解到的情况和大家详细聊聊,希望能帮到正在准备盲审的同学。 盲审流程中AIGC检测处于什么位置? 盲审前的"关卡"越来越多 以前硕士论文盲审,学校主要关注的就是查重率。但从2025年下半年开始,越来越多的高校在盲审前增加了AIGC检测环节。根据我收集到的信息,目前的盲审流程大致是这样的: 环节时间节点负责方是否涉及AI检测论文提交盲审前2-4周研究生院部分学校要求提交检测报告查重检测盲审前1-2周学院/研究生院与AIGC检测同步进行AIGC检测盲审前1-2周学院/研究生院是,多数用知网系统送审盲审开始研究生院统一安排部分学校附带检测报告评审盲审期间(2-4周)外校评委评委可能收到报告 三种常见的学校处理方式 经过调研,我发现不同学校对盲审中AIGC检测的处理方式主要分三种: 第一种:检测不通过直接不送审。 这是最严格的情况。如果AIGC检测率超过

【实践】操作系统智能助手OS Copilot新功能测评

【实践】操作系统智能助手OS Copilot新功能测评

一、引言         数字化加速发展,尤其人工智能的发展速度越来越快。操作系统智能助手成为提升用户体验与操作效率的关键因素。OS Copilot借助语言模型,人工智能等,对操作系统的自然语言交互操作 推出很多功能,值得开发,尤其运维,系统操作等比较适用,优化用户与操作系统的交互模式。本次测评,按照测评指南进行相关测评,得出下面的测评报告。 二、OS Copilot简介         OS Copilot 是一款致力于深度融合于操作系统的智能助手,它旨在成为用户与操作系统交互的得力伙伴 。通过先进的自然语言处理技术和机器学习算法,OS Copilot 能够理解用户多样化的指令,将复杂的操作系统操作简单化。         在日常使用场景中,无论是文件管理、应用程序的操作,还是系统设置的调整,OS Copilot 都能提供高效的支持。例如,在文件管理方面,用户无需手动在层层文件夹中查找文件,只需通过描述文件的大致信息,如创建时间、文件内容关键词等,就能快速定位到目标文件。         对于应用程序,它不仅能根据用户的使用习惯智能启动,还能在应用程序运行时进行优化,确保