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

【C++ | 抽象类】纯虚函数 和 抽象基类,为什么需要抽象基类

😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀
🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭
🤣本文内容🤣:🍭介绍 抽象基类 和 纯虚函数 🍭
😎金句分享😎:🍭你不能选择最好的,但最好的会来选择你——泰戈尔🍭
⏰发布时间⏰:

本文未经允许,不得转发!!!

目录

  • 🎄一、概述
  • 🎄二、纯虚函数
  • 🎄三、抽象基类
  • 🎄四、为什么需要抽象类
  • 🎄五、总结



在这里插入图片描述

🎄一、概述

在生活中,有时会使用到比较抽象的词语,例如下面这个场景:

A:帮我把那个“东西”拿过来。
B:你是说,桌面的那个杯子吗?
A:是的。

这个场景中的“东西”就属于抽象的词语。而在C++编程中,有时也会出现这样抽象的语法。例如,我们可能会定义一个“动物”基类,但代码中不会定义一个“动物”的实例,而是将“动物”基类派生出“狗”、“猫”等派生类,再使用派生类去实例化。

本文主要介绍下面几个内容:
1、什么是纯虚函数?
2、什么是抽象基类?
3、为什么需要抽象基类?


在这里插入图片描述

🎄二、纯虚函数

上篇文章:【C++ | 虚函数】虚函数详解 及 例子代码演示(包含虚函数使用、动态绑定、虚函数表、虚表指针),我们详细地介绍了虚函数以及C++怎样实现虚函数的,但有一个也是很重要的知识点没在上篇文章介绍,这个知识点就是 纯虚函数

纯虚函数:本质上也是虚函数,在虚函数的函数原型的分号前加上=0就可以将一个虚函数说明为纯虚函数。
下面代码声明了一个虚函数 eat:

virtual void eat() =0;

纯虚函数的特点:
1、纯虚函数声明就是在函数原型分号前加=0
2、纯虚函数允许只有声明,没有定义(实现);
3、纯虚函数可以没有定义,也可以有定义,但纯虚函数的定义只能在类外。
4、只有虚函数可以加=0,非虚函数加=0会编译报错:error: initializer specified for non-virtual method

🌰举例子

// g++ 24_pure_virtual.cpp
#include <iostream>
using namespace std;class CAnimal{
public:// 1、纯虚函数声明就是在函数原型分号前加`=0`// 2、纯虚函数允许只有声明,没有定义(实现);virtual void eat() =0;	virtual void run() =0;
};// 3、纯虚函数的定义只能在类外。
inline void CAnimal::run()
{cout << "Animal run" << endl;
}int main ()
{}

在这里插入图片描述

🎄三、抽象基类

抽象基类:英文名称是abstract base class,缩写为ABC。抽象基类是包含了至少一个纯虚函数的基类,在代码中只能用来做基类,不能用来实例化对象。

抽象基类虽然不能实例化对象,但可以定义抽象基类的指针或引用,以此来管理其派生类对象。

抽象基类的特点:
1、抽象基类至少有一个纯虚函数;
2、抽象基类不能创建对象;
3、抽象基类要求派生类必须重写纯虚函数,以此来规范派生类的接口(函数);
4、派生类必须重写抽象基类中的所有纯虚函数,否则也是抽象类,无法实例化对象。
5、抽象基类的纯虚函数一般没有定义,即使有定义也没法创建对象去调用。

🌰举例子

// g++ 24_pure_virtual2.cpp
#include <iostream>
using namespace std;class CAnimal{
public:virtual void eat() =0;	// 纯虚函数,本类是抽象基类virtual void run() =0;
};class CCat : public CAnimal{
public:// 没有重写基类的所有纯虚函数,本类是抽象类virtual void eat(){cout << "cat eat" << endl;}
};class CDog : public CAnimal{
public:// 重写基类的所有纯虚函数,本类不是抽象类virtual void eat(){cout << "dog eat" << endl;}virtual void run(){cout << "dog run" << endl;}
};// 纯虚函数的定义只能在类外。
inline void CAnimal::run()
{cout << "Animal run" << endl;
}int main ()
{//CAnimal animal;	// 报错:error: cannot declare variable ‘animal’ to be of abstract type ‘CAnimal’//CCat cat;	// 报错:error: cannot declare variable ‘cat’ to be of abstract type ‘CCat’CDog dog;CAnimal *pAnimal = &dog;pAnimal->run();pAnimal->CAnimal::run(); // 指定调用基类的run
}

运行结果:
在这里插入图片描述


在这里插入图片描述

🎄四、为什么需要抽象类

之前一直在想,很多代码明明使用普通类也可以,为什么需要定义抽象类呢?

需要定义抽象基类的几个原因:

  • 1、将接口与实现分离。接口是软件产品最有价值的资源,设计接口比实现接口需要耗费更昂贵的成本。因此,要将接口保护起来,以免在针对客户需求修改实现的时候,程序员不小心把接口破坏掉。
    我们将一些必要的接口(函数)定义在抽象类,要求派生类必须按照这个格式去重写,如果不重写就休想创建对象。也就是说,抽象类将具体实现延迟到子类中,提供代码重用性和一定程度的设计约束。
  • 2、避免某些基类被实例化是不合理的。例如“形状”这个基类,被实例化之后反而会让人相当费解,所以干脆将“形状”这个类定义为抽象类,由它派生出正方形,三角形等子类。
  • 3、提示作用,当我们看到抽象基类就会知道其派生类一定会重写纯虚函数,而且也会去找抽象类的指针或引用,看看是否实现多态。其次,看到抽象类也知道它不会定义对象,也就不会去代码里找抽象类的对象了。

在这里插入图片描述

🎄五、总结

本文介绍了C++的纯虚函数、抽象基类,以及怎样使用它们,最后介绍了需要抽象基类的原因。

在这里插入图片描述
如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁

参考:
《C++ primer》
《C++ primer plus》
C++为什么要定义抽象基类?
为什么需要抽象类和接口?
为什么使用抽象类?有什么好处?

相关文章:

【C++ | 抽象类】纯虚函数 和 抽象基类,为什么需要抽象基类

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…...

DP(7) | 打家劫舍① | Java | LeetCode 198, 213, 337 做题总结(未完)

打家劫舍问题 来源于代码随想录&#xff1a;https://programmercarl.com/0198.%E6%89%93%E5%AE%B6%E5%8A%AB%E8%88%8D.html#%E6%80%9D%E8%B7%AF ① 确定dp数组&#xff08;dp table&#xff09;以及下标的含义 dp[i]&#xff1a;考虑下标i&#xff08;包括i&#xff09;以内的房…...

人工智能算法工程师(中级)课程17-模型的量化与部署之剪枝技巧与代码详解

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能算法工程师(中级)课程17-模型的量化与部署之剪枝技巧与代码详解。模型剪枝是深度学习领域中一项关键的技术&#xff0c;旨在减少神经网络中的冗余权重&#xff0c;从而降低计算成本和内存占用&#xff0c;同…...

JavaScript 实例:掌握编程技巧

JavaScript 实例:掌握编程技巧 JavaScript 是一种广泛使用的编程语言,它为网页添加交互性,是现代网络开发的重要组成部分。本文将通过一系列实例,帮助您更好地理解和掌握 JavaScript 的核心概念和编程技巧。 基础实例:变量和数据类型 首先,让我们从最基础的开始。Java…...

自己做小项目时,配置的Maven需要用阿里云私服加速Jar包的下载

在我的IDEA中&#xff0c;maven配置在了这个地址&#xff0c;然后我需要去这个地址下找到settings.xml的maven配置文件来配置以下的阿里云私服地址来加速jar包的下载&#xff01;【不然就是下N年很慢&#xff01;】...

Linux笔记之time命令测量命令的执行时间

Linux笔记之time命令测量命令的执行时间 在Linux中&#xff0c;time命令用于测量命令的执行时间。这对于分析和优化脚本或程序的性能非常有用。time命令会显示三个主要时间指标&#xff1a; real: 从命令开始到结束的实际时间&#xff08;也称为挂钟时间&#xff09;。user: …...

《基于 CDC、Spark Streaming、Kafka 实现患者指标采集》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…...

重要的单元测试

&#x1f47d;System.out.println(“&#x1f44b;&#x1f3fc;嗨&#xff0c;大家好&#xff0c;我是代码不会敲的小符&#xff0c;目前工作于上海某电商服务公司…”); &#x1f4da;System.out.println(“&#x1f388;如果文章中有错误的地方&#xff0c;恳请大家指正&…...

什么是diff算法?

Diff算法&#xff0c;全称为Difference算法&#xff0c;是一种用于比较和查找两个对象&#xff08;如文本、源代码、数据结构或任何形式的字符串&#xff09;之间差异的算法。它在多个领域有着广泛的应用&#xff0c;包括但不限于前端开发、版本控制系统、协同编辑工具等。以下…...

BUUCTF逆向wp [MRCTF2020]Transform

第一步 查壳。该题为64位。 第二步 进入主函数&#xff0c;跟进dword_40F040,它应该与关键字符串有关 分析一下&#xff1a; 初始化和输入 sub_402230(argc, argv, envp); 这行可能是一个初始化函数&#xff0c;用于设置程序环境或处理命令行参数。具体功能不明&#xff0c…...

前端下载文件流 出现乱码 解决方案

1. 后端返回文件格式不是 utf-8 解决方案&#xff1a;后端加 2. 若添加 utf-8 后依旧乱码 请求配置中添加 responseType: arraybuffer, export function downMode() {return http.request({url: baseUrl downTemplate,method: get,responseType: arraybuffer,}); }下载 con…...

Linux/Windows 系统分区

1. Windows 系统 1.1 系统分区 系统分区也叫做磁盘分区&#xff0c;即分盘&#xff1b; 举个例子&#xff0c;好比家里有一个大柜子&#xff0c;把衣服&#xff0c;鞋子&#xff0c;袜子都放在里面&#xff0c;由于没有隔断&#xff0c;找的时候非常麻烦&#xff0c;找是能找…...

C/C++ xml库

文章目录 一、介绍1.1 xml 介绍1.2 xml 标准1.3 xml 教程1.4 xml 构成 二、C/C xml 库选型2.1 选型范围2.2 RapidXML2.3 tinyxml22.4 pugixml2.5 libxml 五、性能比较5.1 C xml 相关的操作有哪些5.2 rapidxml、Pugixml、TinyXML2 文件读取性能比较 六、其他问题6.1 version和 e…...

UniVue@v1.5.0版本发布:里程碑版本

前言 以后使用UniVue都推荐使用1.5.0以后的版本&#xff0c;这个版本之后&#xff0c;更新的速度将会放缓。 希望这个框架能够切实的帮助大家更好的开发游戏&#xff0c;做出一款好游戏&#xff01;本开源项目采用的开源协议为MIT协议&#xff0c;完全开源化&#xff0c;以后也…...

在 Windows 上开发.NET MAUI 应用_2.生成你的第一个应用

先决条件 Visual Studio 2022 17.8 或更高版本&#xff0c;并安装了 .NET Multi-platform App UI 工作负载。 可参考上一篇文章&#xff1a;http://t.csdnimg.cn/n38Yy 创建应用 1.启动 Visual Studio 2022。 在开始窗口中&#xff0c;单击“创建新项目”以创建新项目&#…...

配置SMTP服务器的要点是什么?有哪些限制?

配置SMTP服务器安全性如何保障&#xff1f;如何高效配置服务器&#xff1f; SMTP作为电子邮件发送的核心协议&#xff0c;其配置对于确保邮件的成功传递和安全至关重要。AokSend将详细介绍配置SMTP服务器的关键要点&#xff0c;帮助读者建立一个高效、安全的邮件发送系统。 配…...

图形渲染基础-Unity渲染管线介绍

Unity中的渲染管线渲染场景主要分为三个阶段 剔除&#xff08;Culling&#xff09; 剔除摄像机不可见对象&#xff08;视锥体剔除Frustum Culling&#xff09;和被遮挡对象&#xff08;遮挡剔除Occlusion Culling&#xff09;。 渲染&#xff08;Rendering&#xff09; 将可见…...

junit mockito service

service类单元测试可以有两种方式 1、使用Autowired启用上下文的Bean走业务逻辑&#xff0c;适用于debug调试 2、使用InjectMocks不启用上下文依懒的Bean采用打桩的形式 打桩注意&#xff1a;service通常业务逻辑复杂&#xff0c;Bean的依懒层次可能很深&#xff0c;初用者常…...

k8s学习——升级后的k8s使用私有harbor仓库

升级后的k8s使用了第三方的容器管理器&#xff0c;安装了nerdctl工具来替代docker进行镜像管理。但是使用docker build打包并上传至harbor仓库的镜像&#xff0c;在部署过程中始终拉不下来&#xff0c;报错证书错误。通过journalctl -xe |grep kubelet 或 journalctl -xe |grep…...

Blender4.2版本正式上线,新版本的5个主要功能!

​Blender刚刚推出了备受瞩目的 Blender 4.2 版本&#xff0c;这款软件专为那些在视觉特效、动画制作、游戏开发和可视化设计领域工作的艺术家们量身打造。作为最新的长期稳定更新&#xff0c;Blender 4.2 不仅稳定可靠&#xff0c;还引入了备受期待的“Eevee Next”实时渲染引…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

Reasoning over Uncertain Text by Generative Large Language Models

https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...