news 2026/4/15 7:36:35

每日一个C++知识点|面向对象之多态

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
每日一个C++知识点|面向对象之多态

C++面向对象的三大特性是封装,继承,多态。上两篇文章分别讨论了封装和继承,今天主要是讲解C++的另一个面向对象的特性~~多态

多态的概念

什么是多态呢?
多态的核心是"同一个接口,不同的实现"
简单来说,就是调用同一个函数名,程序会根据上下文和调用对象的实际类型来自动执行对应的函数逻辑,后面我们将会用代码来举例说明

多态的分类

C++多态分为静态多态动态多态

静态多态

静态多态是编译时多态,编译器在编译阶段就确定要调用的函数版本,主要通过函数重载、模板实现,用代码举例如下:

#include<iostream>usingnamespacestd;// 重载1:计算两个整数的和intadd(inta,intb){returna+b;}// 重载2:计算三个浮点数的和doubleadd(doublea,doubleb,doublec){returna+b+c;}intmain(){cout<<add(12)<<endl;// 调用int版本,输出3cout<<add(1.12.23.3)<<endl;// 调用double版本,输出6.6return0;}

这里编译器根据参数的个数、类型,在编译时就确定了要调用的add()函数

动态多态

动态多态是运行时多态,程序在运行阶段才确定要调用的函数版本

动态多态的实现需要以下三个条件

  1. 存在继承关系
  2. 父类声明虚函数,子类重写该虚函数
  3. 使用父类的指针指向子类对象

由于还没有说到虚函数,暂时先不用代码举例,等说完虚函数再一并举例

虚函数

上面说到虚函数是动态多态实现的必要条件之一,那么什么是虚函数呢?

普通虚函数

虚函数是在父类中用virtual关键字修饰的成员函数,调用时要根据对象的实际类型来动态绑定,而不是编译时固定绑定

// 父类:图形classShape{public:// 虚函数:绘制图形virtualvoiddraw(){cout<<"绘制基础图形"<<endl;}doublegetArea(){return1;}};

上述代码中,用virtual关键字修饰的draw()函数就是虚函数,调用时要根据对象的实际类型来决定其内容,假如它的子类如下所示:

// 子类:圆形classCircle:publicShape{private:doubleradius;public:Circle(doubler):radius(r){}// 重写父类的虚函数(override关键字可选,但建议加)voiddraw()override{cout<<"绘制半径为"<<radius<<"的圆形"<<endl;}doublegetArea(){returnM_PI*radius*radius;}};

上述代码中子类Circle的成员函数draw()有关键字override来修饰,是对父类虚函数draw()的重写,假如调用情况如下所示:

intmain(){// 父类指针指向子类对象(多态的关键)Shape*shape=newCircle(5.0);// 调用的是子类Circle的draw和getArea(动态绑定)shape->draw();// 输出:绘制半径为5的圆形cout<<"面积:"<<shape->getArea()<<endl;// 输出:面积:78.5398deleteshape;return0;}

由于实际的对象由Shape* shape = new Circle(5.0);决定,所以draw()函数是执行Circle类的内容而不是父类Shape的内容

这就是虚函数的内容,也是动态多态的内容(满足动态多态的三个条件)

虚函数的实现原理

我们已经知道了虚函数的用法,那么虚函数是怎么实现动态多态的呢?下面我们简单了解其原理

编译器为了实现虚函数的动态绑定做了两件事:分别是创建虚函数表添加虚表指针

虚函数表是每个包含虚函数的类(包括父类和子类)都会有一个独立的虚函数表,表中存储了该类所有虚函数的地址。上述代码中Shape类和Circle类都有各自的虚函数表,表中存储虚函数draw()的地址

虚表指针是每个对象会包含一个隐藏的虚表指针,指向所属类的虚函数表。上述代码Shape* shape = new Circle(5.0);中的对象shape存在一个虚函数指针,指向Circle类里的虚函数表里的draw()的地址

当程序运行时,通过对象的虚表指针找到对应的虚函数表,再调用表中的函数地址,从而实现 “根据对象实际类型调用函数”

纯虚函数

上述虚函数的例子是有实际意义的,有时候父类的虚函数没有实现意义,这时可以定义纯虚函数,格式是在函数后加 = 0

classShape{public:// 纯虚函数:没有函数体,强制子类必须重写virtualdoublegetArea()=0;// 普通虚函数可以有默认实现virtualvoiddraw(){std::cout<<"绘制基础图形"<<std::endl;}virtual~Shape(){}};

包含纯虚函数的类称为抽象类,不能实例化对象,只能作为基类被继承,同时子类必须重写所有纯虚函数

虚析构函数

当类中有虚函数时,必须将析构函数声明为虚函数,否则会导致内存泄漏,代码如下:

#include<iostream>#include<cmath>usingnamespacestd;classShape{public:// 1. 业务虚函数(多态的核心接口)virtualvoiddraw()=0;// 纯虚函数,强制子类实现virtualdoublegetArea()=0;// 2. 虚析构函数(配合多态删除场景,必须加)virtual~Shape(){cout<<"Shape析构"<<endl;}};classCircle:publicShape{private:doubleradius;public:Circle(doubler):radius(r){}// 重写业务虚函数voiddraw()override{cout<<"绘制圆形,半径:"<<radius<<endl;}doublegetArea()override{returnM_PI*radius*radius;}~Circle()override{cout<<"Circle析构"<<endl;}};intmain(){// 多态场景:父类指针指向子类对象Shape*shape=newCircle(5.0);shape->draw();// 调用子类的draw(业务虚函数的作用)deleteshape;// 调用子类的析构(虚析构函数的作用)return0;}

上述代码中由于Shape类和Circle类都有虚函数,所以必须要有虚析构函数,避免内存泄漏

如果想更深入了解虚析构函数可以看我往期关于虚析构函数的文章,那里有更具体的描述~

总结

本文通过动态的概念、分类、虚函数、纯虚函数、虚析构函数这几个方面来描述了C++面向对象之多态的内容,并通过具体代码示例来深入分析多态的实现原理和演示多态的实现过程

本文暂时写到这里,如果文章对你有用的话欢迎点赞收藏~

感兴趣的话也可以关注我,我会持续输出C++相关的内容~

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/9 19:51:03

Open-AutoGLM实战手册:7个关键命令让你轻松掌控千万级进程流

第一章&#xff1a;Open-AutoGLM实战入门指南环境准备与依赖安装 在开始使用 Open-AutoGLM 之前&#xff0c;需确保本地已配置 Python 3.9 环境。推荐使用虚拟环境以隔离项目依赖。创建虚拟环境&#xff1a;python -m venv open-autoglm-env激活环境&#xff08;Linux/macOS&am…

作者头像 李华
网站建设 2026/4/9 7:46:10

基于Java的幼儿园管理系统

摘 要 随着信息时代的来临&#xff0c;过去的传统管理方式缺点逐渐暴露&#xff0c;对过去的传统管理方式的缺点进行分析&#xff0c;采取计算机方式构建幼儿园管理系统。本文通过课题背景、课题目的及意义相关技术&#xff0c;提出了一种教 学生信息、学生考勤、健康记录、成长…

作者头像 李华
网站建设 2026/4/14 1:47:35

Open-AutoGLM定时任务配置实战(专家级配置方案曝光)

第一章&#xff1a;Open-AutoGLM定时任务配置概述Open-AutoGLM 是一款基于 AutoGLM 框架构建的自动化任务调度系统&#xff0c;专为大语言模型的周期性推理与数据处理任务设计。其核心功能之一是支持灵活的定时任务配置&#xff0c;使用户能够按需执行模型推理、结果上报与日志…

作者头像 李华
网站建设 2026/4/12 12:46:14

你真的会监控Open-AutoGLM吗?3个被忽视的关键指标必须掌握

第一章&#xff1a;你真的了解Open-AutoGLM的监控挑战吗在部署和运维 Open-AutoGLM 这类开源大语言模型自动化系统时&#xff0c;监控不仅是保障服务稳定的核心环节&#xff0c;更是发现潜在性能瓶颈与安全风险的关键手段。然而&#xff0c;许多团队在实践中低估了其复杂性&…

作者头像 李华
网站建设 2026/4/12 12:15:04

如何让Open-AutoGLM在服务器重启后自动恢复?关键配置详解

第一章&#xff1a;Open-AutoGLM 开机自动启动概述Open-AutoGLM 是一款基于 GLM 架构的开源自动化工具&#xff0c;专为系统级任务调度与服务自启设计。其核心功能之一是在操作系统启动时自动加载并运行指定服务&#xff0c;从而实现无人值守环境下的持续运作。该机制广泛应用于…

作者头像 李华
网站建设 2026/4/14 9:07:10

模型推理卡顿不断?,深度剖析Open-AutoGLM资源调度陷阱及优化路径

第一章&#xff1a;模型推理卡顿不断&#xff1f;深度剖析Open-AutoGLM资源调度陷阱及优化路径在部署 Open-AutoGLM 模型进行大规模推理时&#xff0c;频繁出现的卡顿现象往往并非源于模型本身&#xff0c;而是资源调度机制中的隐性瓶颈所致。特别是在多实例并发、显存动态分配…

作者头像 李华