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

从静态多态、动态多态到虚函数表、虚函数指针

        多态(Polymorphism)是面向对象编程中的一个重要概念,它允许不同类的对象对同一消息做出不同的响应。多态性使得可以使用统一的接口来操作不同类的对象,从而提高了代码的灵活性和可扩展性。

一、多态的表现形式

1. 静态多态(编译时多态)

        静态多态主要通过函数重载、运算符重载以及模板来实现。通过不同的参数列表、泛型类来选择合适的函数。

重载

#include <iostream>void print(int a) {std::cout << "Integer: " << a << std::endl;
}void print(double a) {std::cout << "Double: " << a << std::endl;
}int main() {print(10);    // 调用 void print(int)print(10.5);  // 调用 void print(double)return 0;
}

模板

#include <iostream>template <typename T>
void print(T a) {std::cout << "Value: " << a << std::endl;
}int main() {print(10);    // 生成 void print<int>(int)print(10.5);  // 生成 void print<double>(double)return 0;
}
2. 动态多态(运行时多态)

        动态多态主要由虚函数和继承来实现,根据对象的实际类型来调用相应的函数。

#include <iostream>class Base {
public:virtual void print() const {    // 如果这里将virtual注释掉,下面两个都会输出"Base"std::cout << "Base" << std::endl;}virtual ~Base() {} // 虚析构函数
};class Derived : public Base {
public:void print() const override {std::cout << "Derived" << std::endl;}
};int main() {Base* basePtr = new Base();Base* derivedPtr = new Derived();basePtr->print();     // 输出 "Base"derivedPtr->print();  // 输出 "Derived"delete basePtr;delete derivedPtr;return 0;
}

        上面的代码中又提到了把virtual注释掉的情况,这涉及到了 “静态类型” “动态类型” 。在这一部分结束之后会讲到。

二、虚函数表、虚函数指针

        虚函数通过运行时的动态绑定,来实现在子类中重写基类的函数。虚函数的原理可以通过虚函数表、虚函数指针来解释。

1. VTable和vptr

        ·每个包含虚函数的类,都有一个虚函数表VTable,是一个指向函数指针的数组。

        ·每个对象创建之后,会有一个虚函数指针vptr,指向类的虚函数表VTable。

        ·当调用虚函数时,会通过vptr查找VTable,然后调用对应的函数。

2. 构造函数不能是虚函数

        在对象创建时,编译器会给对象的vptr赋值,然后再调用构造函数,如果构造函数是虚函数,此时就陷入了死循环。

3. 析构函数可以是虚函数

        通过将基类的析构函数声明为虚函数,可以确保在通过基类指针删除子类对象时,调用到子类的析构函数,合适地释放资源。

#include <iostream>class Base {
public:virtual ~Base() {std::cout << "Base destructor" << std::endl;}
};class Derived : public Base {
public:~Derived() {std::cout << "Derived destructor" << std::endl;}
};int main() {Base* ptr = new Derived();delete ptr; // 先调用 Derived 的析构函数,然后再调用 Base 的析构函数return 0;
}

三、静态类型、动态类型

        静态类型:是指对象在声明时的类型,在编译期已既定。

        动态类型:一个指针、引用目前指向的对象的类型,在运行时确定的。

再来看我们刚才的代码。

        在函数调用时,虚函数会根据动态类型来调用,而普通函数就通过静态类型

#include <iostream>class Base {
public:/*virtual*/ void print() const {    // 将virtual注释掉,下面两个都会输出"Base"std::cout << "Base" << std::endl;}
};class Derived : public Base {
public:    void print() const /*override*/ {    // override和上面的virtual对应std::cout << "Derived" << std::endl;}
};int main() {Base* basePtr = new Base();        // 静态类型Base,动态类型BaseBase* derivedPtr = new Derived();  // 静态类型Base,动态类型DerivedDerived* thirdPtr = new Derived(); // 静态类型Derived,动态类型DerivedbasePtr->print();     // 输出 "Base"derivedPtr->print();  // 输出 "Base"thirdPtr->print();    // 输出 "Derived"delete basePtr;delete derivedPtr;delete thirdPtr;return 0;
}

四、static_cast和dynamic_cast的安全与否

1. static_cast

static_cast是一种显式类型转换,主要用于已知的类型转换。

  • 向上转型(从派生类指针或引用转换为基类指针或引用)是安全的,因为派生类对象可以被视为基类对象的一个特例。
  • 基本类型转换(如 int 到 double)也是安全的。
  • 不进行运行时检查,因此在某些情况下可能会导致未定义行为,特别是当进行向下转型时。
2. dynamic_cast

dynamic_cast是一种运行时类型检查的类型转换,主要用于多态类型之间的转换。

  • 向上转型(从派生类指针或引用转换为基类指针或引用)是安全的。
  • 向下转型(从基类指针或引用转换为派生类指针或引用)是安全的,因为它会在运行时检查类型的有效性。
  • 运行时检查类型安全,如果转换不成功,会返回 nullptr(对于指针)或抛出 std::bad_cast 异常(对于引用)。

 

相关文章:

从静态多态、动态多态到虚函数表、虚函数指针

多态&#xff08;Polymorphism&#xff09;是面向对象编程中的一个重要概念&#xff0c;它允许不同类的对象对同一消息做出不同的响应。多态性使得可以使用统一的接口来操作不同类的对象&#xff0c;从而提高了代码的灵活性和可扩展性。 一、多态的表现形式 1. 静态多态&…...

用 Pygame 实现一个乒乓球游戏

用 Pygame 实现一个乒乓球游戏 伸手需要一瞬间&#xff0c;牵手却要很多年&#xff0c;无论你遇见谁&#xff0c;他都是你生命该出现的人&#xff0c;绝非偶然。若无相欠&#xff0c;怎会相见。 引言 在这篇文章中&#xff0c;我将带领大家使用 Pygame 库开发一个简单的乒乓球…...

基于大数据可视化的化妆品推荐及数据分析系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…...

Java项目实战II基于Java+Spring Boot+MySQL的汽车销售网站(文档+源码+数据库)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 在数字化时…...

数学基础 -- 微积分最优化之一个最简单的例子

微积分中的一个最简单的最优化例子 问题描述 假设你有一条长度为 10 米的栅栏&#xff0c;你需要围成一个矩形的鸡舍&#xff0c;使得围成的面积最大。求这个矩形的长和宽应是多少&#xff0c;以使得面积最大。 步骤 设定变量&#xff1a; 设矩形的长为 x x x 米&#xff0…...

kubernetes K8S 结合 Istio 实现流量治理

目录 1.Istio介绍&#xff1f; 1.1 Istio是什么&#xff1f; 1.2 Istio流量管理 1.2.1 熔断 1.2.2 超时 1.2.3 重试 2.Istio架构 3.istio组件详解 3.1 Pilot 3.2 Envoy 3.3 Citadel 3.4 Galley 3.5 Ingressgateway 3.5 egressgateway 扩展、k8s1.23及1.23以下版…...

Selenium with Python学习笔记整理(网课+网站持续更新)

本篇是根据学习网站和网课结合自己做的学习笔记&#xff0c;后续会一边学习一边补齐和整理笔记 非常推荐白月黑羽的学习网站&#xff1a; 白月黑羽 (byhy.net) https://selenium-python.readthedocs.io/getting-started.html#simple-usage WEB UI自动化环境配置 (推荐靠谱…...

1.随机事件与概率

第一章 随机时间与概率 1. 随机事件及其运算 1.1 随机现象 ​ 确定性现象&#xff1a;只有一个结果的现象 ​ 确定性现象&#xff1a;结果不止一个&#xff0c;且哪一个结果出现&#xff0c;人们事先并不知道 1.2 样本空间 ​ 样本空间&#xff1a;随机现象的一切可能基本…...

Redis结合Caffeine实现二级缓存:提高应用程序性能

本文将详细介绍如何使用CacheFrontend和Caffeine来实现二级缓存。 1. 简介 CacheFrontend: 是一种用于缓存的前端组件或服务。通俗的讲&#xff1a;该接口可以实现本地缓存与redis自动同步&#xff0c;如果本地缓存&#xff08;JVM级&#xff09;有数据&#xff0c;则直接从本…...

【LLM】Ollama:本地大模型 WebAPI 调用

Ollama 快速部署 安装 Docker&#xff1a;从 Docker 官网 下载并安装。 部署 Ollama&#xff1a; 使用以下命令进行部署&#xff1a; docker run -d -p 11434:11434 --name ollama --restart always ollama/ollama:latest进入容器并下载 qwen2.5:0.5b 模型&#xff1a; 进入 O…...

SpringBoot集成阿里easyexcel(二)Excel监听以及常用工具类

EasyExcel中非常重要的AnalysisEventListener类使用&#xff0c;继承该类并重写invoke、doAfterAllAnalysed&#xff0c;必要时重写onException方法。 Listener 中方法的执行顺序 首先先执行 invokeHeadMap() 读取表头&#xff0c;每一行都读完后&#xff0c;执行 invoke()方法…...

使用ELK Stack进行日志管理和分析:从入门到精通

在现代IT运维中&#xff0c;日志管理和分析是确保系统稳定性和性能的关键环节。ELK Stack&#xff08;Elasticsearch, Logstash, Kibana&#xff09;是一个强大的开源工具集&#xff0c;广泛用于日志收集、存储、分析和可视化。本文将详细介绍如何使用ELK Stack进行日志管理和分…...

前端框架对比与选择

&#x1f916; 作者简介&#xff1a;水煮白菜王 &#xff0c;一位资深前端劝退师 &#x1f47b; &#x1f440; 文章专栏&#xff1a; 前端专栏 &#xff0c;记录一下平时在博客写作中&#xff0c;总结出的一些开发技巧✍。 感谢支持&#x1f495;&#x1f495;&#x1f495; 目…...

Springboot jPA+thymeleaf实现增删改查

项目结构 pom文件 配置相关依赖&#xff1a; 2.thymeleaf有点类似于jstlel th:href"{url}表示这是一个链接 th:each"user : ${users}"相当于foreach&#xff0c;对user进行循环遍历 th:if进行if条件判断 {变量} 与 ${变量}的区别: 4.配置好application.ym…...

【YashanDB知识库】yashandb执行包含带oracle dblink表的sql时性能差

本文内容来自YashanDB官网&#xff0c;具体内容请见https://www.yashandb.com/newsinfo/7396959.html?templateId1718516 问题现象 yashandb执行带oracle dblink表的sql性能差&#xff1a; 同样的语句&#xff0c;同样的数据&#xff0c;oracle通过dblink访问远端oracle执行…...

效率工具推荐 | 高效管理客服中心知识库

人工智能AI的广泛应用&#xff0c;令AI知识库管理已成为优化客服中心运营的核心策略之一。一个高效、易用且持续更新的知识库不仅能显著提升客服代表的工作效率&#xff0c;还能极大提升客户的服务体验。而高效效率工具如HelpLook&#xff0c;能够轻松搭建AI客服帮助中心&#…...

综合实验1 利用OpenCV统计物体数量

一、实验简介 传统的计数方法常依赖于人眼目视计数&#xff0c;不仅计数效率低&#xff0c;且容易计数错误。通常现实中的对象不会完美地分开&#xff0c;需要通过进一步的图像处理将对象分开并计数。本实验巩固对OpenCV的基础操作的使用&#xff0c;适当的增加OpenCV在图像处…...

[Redis][主从复制][上]详细讲解

目录 0.前言1.配置1.建立复制2.断开复制3.安全性4.只读5.传输延迟 2.拓扑1.一主一从结构2.一主多从结构2.树形主从结构 0.前言 说明&#xff1a;该章节相关操作不需要记忆&#xff0c;理解流程和原理即可&#xff0c;用的时候能自主查到即可主从复制&#xff1f; 分布式系统中…...

【算法】leetcode热题100 146.LRU缓存. container/list用法

https://leetcode.cn/problems/lru-cache/description/?envTypestudy-plan-v2&envIdtop-100-liked 实现语言&#xff1a;go lang LRU 最近最少未使用&#xff0c;是一种淘汰策略&#xff0c;当缓存空间不够使用的时候&#xff0c;淘汰一个最久没有访问的存储单元。目前…...

[论文总结] 深度学习在农业领域应用论文笔记13

文章目录 1. Downscaling crop production data to fine scale estimates with geostatistics and remote sensing: a case study in mapping cotton fibre quality &#xff08;Precision Agriculture &#xff0c;2024&#xff0c; IF5.585&#xff09;背景方法结果结论个人总…...

2026金三银四变天了:企业要的是能用的人,不是“有潜力的人“

2026金三银四变天了&#xff1a;企业要的是"能用的人"&#xff0c;不是"有潜力的人" 3月了&#xff0c;又到了传说中的"金三银四"。 往年这个时候&#xff0c;朋友圈里都是"拿到offer了""跳槽涨薪30%"的好消息。但今年&…...

别再死记硬背了!用74HC系列CMOS芯片,手把手带你理解逻辑门电平与噪声容限

74HC系列CMOS芯片实战&#xff1a;从数据手册到面包板的逻辑门电平全解析 当你在深夜调试一块74HC04反相器搭建的振荡电路时&#xff0c;示波器上本该清晰的方波却出现了毛刺和畸变——这种场景对电子爱好者来说再熟悉不过。本文将以74HC系列CMOS芯片为核心&#xff0c;通过五…...

LangChain实战避坑:我的RAG项目为什么召回结果不准?从向量化到混合检索的调优全记录

LangChain实战调优&#xff1a;从召回失败到精准检索的完整解决方案 当你的RAG系统在回答"夏天旅行推荐"时&#xff0c;返回了撒哈拉沙漠海滩和新疆火山口这类荒谬结果&#xff0c;问题可能出在文本分割、嵌入模型或混合检索策略上。本文将分享一套经过实战验证的调优…...

UDOP-large实战手册:英文技术文档FAQ自动生成Prompt模板库

UDOP-large实战手册&#xff1a;英文技术文档FAQ自动生成Prompt模板库 1. 引言&#xff1a;当技术文档遇上智能问答 想象一下这个场景&#xff1a;你刚拿到一份50页的英文技术白皮书&#xff0c;需要快速了解它的核心内容。传统做法是什么&#xff1f;打开PDF&#xff0c;从头…...

医疗AI智能体:从数据到关怀人文设计:告别冰冷精准,构建有温度的诊疗交互.131

一、智能体的人文设计医疗AI智能体以大模型为核心&#xff0c;串联医学知识图谱、实体识别模块、风险评估模块、话术生成模块、伦理审核模块五大核心组件&#xff0c;最终实现精准医学判断 人性化交互的双重目标。而在医疗场景中&#xff0c;用户的核心需求从来不是单纯的数据…...

2026年华为云OpenClaw如何安装?配置百炼API零门槛10分钟步骤

2026年华为云OpenClaw如何安装&#xff1f;配置百炼API零门槛10分钟步骤。OpenClaw&#xff08;曾用名Clawdbot&#xff09;是一款轻量化、可扩展的开源AI智能体执行框架&#xff0c;支持自然语言指令驱动、多模型灵活切换与全场景任务自动化。对于新手而言&#xff0c;阿里云轻…...

Qwen3.5-9B图文对话实战:工业设备铭牌识别+参数查询+维保周期提醒

Qwen3.5-9B图文对话实战&#xff1a;工业设备铭牌识别参数查询维保周期提醒 1. 项目概述 Qwen3.5-9B是一款拥有90亿参数的开源大语言模型&#xff0c;特别适合工业场景下的图文对话应用。这个项目展示了如何利用其多模态能力&#xff0c;实现工业设备铭牌识别、参数查询和维保…...

S2-Pro在Windows系统的一键部署与简易客户端开发

S2-Pro在Windows系统的一键部署与简易客户端开发 1. 引言 如果你是一名Windows用户&#xff0c;想要快速体验S2-Pro的强大能力&#xff0c;但又不想折腾复杂的命令行操作&#xff0c;这篇文章就是为你准备的。我们将从零开始&#xff0c;带你完成两个关键步骤&#xff1a; 在…...

Dan Koe: 如果你有多重兴趣,请不要浪费接下来的2-3年

本文整理自 Dan Koe 原文。Dan Koe 是 YouTube、X 等平台拥有数百万粉丝的个人成长领域创作者&#xff0c;以"一人公司"理念、深度内容创作和高效 AI 工作流著称。你是否曾因为无法只专注一件事而感到自责&#xff1f; 你学设计&#xff0c;又想学编程&#xff1b;读…...

从农田到实验室:大疆P4M多光谱数据与ASD地物波谱仪实测数据对比实操指南

从农田到实验室&#xff1a;大疆P4M多光谱数据与ASD地物波谱仪实测数据对比实操指南 当无人机掠过农田上空&#xff0c;搭载的多光谱传感器正在以厘米级分辨率记录作物的生理状态。这些数据能否真实反映地表反射特性&#xff1f;本文将以大疆P4M多光谱无人机与ASD FieldSpec系…...