C++纯虚函数的理解,纯虚函数和派生类的关系。

在 C++ 中,纯虚函数(pure virtual function)是一种特殊的虚函数,它在基类中没有实现,只定义了一个接口,要求派生类必须提供具体实现。纯虚函数的定义方式在接口设计和多态性中非常有用。

纯虚函数的定义和语法

在 C++ 中,纯虚函数的定义使用以下语法:

class Base {
public:virtual void pureVirtualFunction() = 0;  // 纯虚函数
};
  • 这里 = 0 表示这是一个纯虚函数,它没有在 Base 类中实现。
  • 任何派生类都必须实现 pureVirtualFunction,否则该派生类也会变成抽象类,不能被实例化。

抽象类

包含至少一个纯虚函数的类称为抽象类(abstract class)。抽象类不能直接创建对象(实例化)。它主要用于作为接口类或基类,要求派生类实现特定的行为。

例如:

class Shape {
public:virtual void draw() = 0;  // 纯虚函数virtual double area() = 0;  // 纯虚函数
};class Circle : public Shape {
public:void draw() override {// Circle 的具体绘制实现}double area() override {// 计算并返回 Circle 的面积}
};class Rectangle : public Shape {
public:void draw() override {// Rectangle 的具体绘制实现}double area() override {// 计算并返回 Rectangle 的面积}
};

在上面的例子中,Shape 是一个抽象类,定义了纯虚函数 drawarea。任何继承自 Shape 的类(例如 CircleRectangle)都必须实现这些函数。

纯虚函数的要求和特性

示例代码

下面是一个实际使用纯虚函数的示例:

  1. 纯虚函数不能在基类中实现: 纯虚函数在基类中没有实现,只有声明。这意味着它仅仅定义了一个接口或合同,具体实现由派生类提供。

  2. 派生类必须实现纯虚函数: 任何继承包含纯虚函数的类的非抽象派生类,必须实现这些纯虚函数,否则该派生类也会成为抽象类。

  3. 抽象类不能实例化: 包含纯虚函数的类不能直接创建对象(实例化)。它们通常用于定义接口和通用行为,强制派生类提供具体实现。

  4. 可以在派生类中覆盖实现: 派生类可以提供自己对纯虚函数的实现,这也是多态性的基础。例如,上面的 CircleRectangle 都实现了 Shape 的纯虚函数。

  5. 可以有实现的纯虚函数: 虽然纯虚函数本身在基类中没有实现,但在一些特殊情况下,可以为纯虚函数提供一个默认的实现,只是这种实现不会改变它作为纯虚函数的性质。例如:

    class Base {
    public:virtual void pureVirtualFunction() = 0;  // 纯虚函数
    };void Base::pureVirtualFunction() {// 纯虚函数的默认实现
    }
    

  6. 这种情况下,派生类仍然需要实现 pureVirtualFunction,否则它们将无法实例化。

  7. 使用纯虚函数的场景

  8. 定义接口: 纯虚函数常用于定义接口类,指定某些操作的合同,而不提供具体实现。例如,定义一个通信接口,要求所有的通信协议实现类都必须实现发送和接收方法。

  9. 强制派生类实现某些功能: 通过将函数声明为纯虚,基类可以强制派生类提供这些函数的具体实现,从而确保派生类具有一致的行为。

  10. 支持多态: 使用纯虚函数可以在运行时通过基类指针或引用调用派生类的实现,实现多态行为。

    #include <iostream>class Animal {
    public:virtual void speak() = 0;  // 纯虚函数
    };class Dog : public Animal {
    public:void speak() override {std::cout << "Woof!" << std::endl;}
    };class Cat : public Animal {
    public:void speak() override {std::cout << "Meow!" << std::endl;}
    };int main() {Animal* dog = new Dog();Animal* cat = new Cat();dog->speak();  // 输出: Woof!cat->speak();  // 输出: Meow!delete dog;delete cat;return 0;
    }
    

    在这个例子中,Animal 类定义了一个纯虚函数 speakDogCat 类必须实现 speak 函数。在 main 函数中,通过基类指针调用派生类的 speak 实现,实现了多态行为。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/38588.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PAI3D: Painting Adaptive Instance-Prior for 3D Object Detection论文讲解

PAI3D: Painting Adaptive Instance-Prior for 3D Object Detection论文讲解 1. 引言2. PAI3D框架2.1 Instance Painter2.2 Adaptive Projection Refiner2.3 Fine-granular Detection Head 3. 实验结果3.1 消融实验 1. 引言 3D目标检测对于自动驾驶来说是一个非常重要的模块&a…

如何现代的编译和安装内核

前言&#xff1a;本文是在阅读书目时找到了一篇非常高质量的文章。的原文是英文&#xff0c;现在我自己手头翻译了一下&#xff0c;发布到这里。 原文连接&#xff1a;How to compile a Linux kernel in the 21st century | Opensource.com 目录 更新内核的现代方法 安装内…

C++知识点总结全系列 (05):IO 类的详细总结和分析

1、基类 istream 和 ostream (1)istream A.What 输入流的抽象类&#xff0c;是所有输入流类的基类 B.Why&#xff08;输入流的作用&#xff09; 用于从数据源&#xff08;如文件、标准输入设备等&#xff09;读取数据 (2)ostream A.What 输出流的抽象类&#xff0c;是所有输…

grpc学习golang版( 六、服务器流式传输 )

系列文章目录 第一章 grpc基本概念与安装 第二章 grpc入门示例 第三章 proto文件数据类型 第四章 多服务示例 第五章 多proto文件示例 第六章 服务器流式传输 第七章 客户端流式传输 第八章 双向流示例 文章目录 一、前言二、定义proto文件三、拷贝任意文件进项目四、编写serve…

复制完若依后,idea没有maven窗口

右击项目 添加框架 添加maven框架就可以了

使用Java实现实时数据处理系统

使用Java实现实时数据处理系统 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 引言 在当今信息爆炸的时代&#xff0c;实时数据处理系统变得越来越重要。无论…

protobuf C++通过协议名获取协议类实例

当知道协议名称时&#xff0c;要获取类的实例有很多种方法 方案一&#xff1a;通过协议名和类实例化绑定&#xff0c;注册到变量&#xff0c;使用的时候再通过名字查找 方案二&#xff1a;通过protobuf自带的查找接口实现&#xff0c;代码如下&#xff1a; #include <iostr…

大数据开发中的数据倾斜问题

数据倾斜是大数据开发中常见的性能瓶颈&#xff0c;了解其原因并采取有效的解决方案对系统性能至关重要。本文将从数据倾斜的影响、解决方法及示例代码等方面进行详细讨论。 目录 1. 数据倾斜的影响2. 解决数据倾斜的方法调整分区键预聚合倾斜处理逻辑 3. 进一步解决数据倾斜的…

vue3.0 + vant实现下拉刷新上拉加载

在vue中使用vant组件库有个van-pull-refresh下拉组件&#xff0c;配合van-list列表组件实现页面的下拉刷新和上拉加载&#xff0c;原理简单&#xff0c;适用场景在列表页面内容展示。 下拉刷新 PullRefresh 实现下拉刷新的效果。 PullRefresh组件中的searchRefreshing属性&…

51单片机嵌入式开发:STC89C52环境配置到点亮LED

STC89C52环境配置到点亮LED 1 环境配置1.1 硬件环境1.2 编译环境1.3 烧录环境 2 工程配置2.1 工程框架2.2 工程创建2.3 参数配置 3 点亮一个LED3.1 原理图解读3.2 代码配置3.3 演示 4 总结 1 环境配置 1.1 硬件环境 硬件环境采用“华晴电子”的MINIEL-89C开发板&#xff0c;这…

安卓app开发-基础-本地环境安装android studio且配置参数

安卓app开发-基础-本地环境安装android studio且配置参数&#xff01;今天为大家介绍一下&#xff0c;如何在自己本地电脑安装android ,studio和启动一个简单的java版本的项目。 第一步&#xff0c;去下面的地址&#xff0c;下载一个安装文件。 地址&#xff1a;AndroidDevToo…

root密码忘了怎么办(从系统引导过程解决)

目录 1.Linux系统密码忘记 2.系统引导过程 2.1 systemd 2.2 GRUB和GRUB2 2.3 运行级别 3.修复MBR扇区故障和GRUB引导故障 3.1 MBR扇区故障 3.2 GRUB引导故障 1.Linux系统密码忘记 我们在生活中经常遇到这类困扰&#xff0c;就是某个账号还是账户密码忘了&#xff0c;这…

第十八章 条件语句(Python)

文章目录 前言一、if 和 else 语句一、if、elif 和 else 多重条件判断语句三、if 语句嵌套 前言 Python 条件语句是通过一条或多条语句的执行结果&#xff08;True 或者 False&#xff09;来决定执行的代码块。 一、if 和 else 语句 语法格式如下&#xff1a;if 要判断的条件…

Docker的理解

Docker的理解 Docker为什么用Docker&#xff1f;1.提升系统资源利用率2.更快速的交付和部署3.高效的部署和扩容4.更简单的管理 Docker核心技术Docker镜像Docker容器Docker仓库 Docker实现原理Linux NamespaceCgroupUnion FS Docker的应用场景1.微服务架构2.持续集成3.快速部署和…

职场内部协同困难?揭秘企业内部沟通问题的根源与解决方案!

在现代职场中&#xff0c;内部协同是非常重要的一环。良好的内部协同可以提高团队的效率和凝聚力&#xff0c;但是在实际工作中&#xff0c;很多企业都会面临内部沟通问题&#xff0c;导致协同困难。那么&#xff0c;企业内部沟通问题的根源是什么&#xff1f;又该如何解决呢&a…

DP V2.1a标准学习

一、说明 DP是DisplayPort的简写,是视频电子标准协会(VESA)标准化的数字式视频接口标准,可用于板内芯片之间的连接,也可用于输出接口连接外部设备。DisplayPort是一种基于数据包的可扩展协议,用于传输视频和音频数据。DisplayPort 具有高度可扩展性,并具有保持向后兼容…

【一步一步了解Java系列】:对这个系列的总结以及对缺漏内部类知识的补充

看到这句话的时候证明&#xff1a;此刻你我都在努力 加油陌生人 br />个人主页&#xff1a;Gu Gu Study专栏&#xff1a;一步一步了解Java 喜欢的一句话&#xff1a; 常常会回顾努力的自己&#xff0c;所以要为自己的努力留下足迹 喜欢的话可以点个赞谢谢了。 作者&#xf…

文件中插入数据(指定内容数据上传,下载,,和本地文件同名)

文件中要插入数据,还需要保持原来的格式可以覆盖,但是不能忽略插入以后的数据?最近客户有这样的一个需求,本来我们的文件读取是以二进制流的方式读取和写入的,客户变更了方法,我们该如何解决呢?数据文件还需要上传,下载,命名都和原来文件一致. 为了解决这个问题,我们需要解决…

《昇思25天学习打卡营第27天 | 昇思MindSporeShuffleNet图像分类》

27天 本节学习了ShuffleNet图像分类 ShuffleNetV1是旷视科技提出的一种计算高效的CNN模型&#xff0c;和MobileNet, SqueezeNet等一样主要应用在移动端&#xff0c;模型的设计目标就是利用有限的计算资源来达到最好的模型精度。设计核心是引入了两种操作&#xff1a;Pointwis…

【Python机器学习】模型评估与改进——分组交叉验证

分组交叉验证是非常常见的一种交叉验证策略&#xff0c;它适用于数据中的分组高度相关时。比如我们想构建一个从人脸图片中识别情感的系统&#xff0c;并且收集了100个人的照片的数据集&#xff0c;其中每个人都进行了多次拍摄&#xff0c;分别展示了不同的情感。我们的目标是构…