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

C++虚函数与多态

C++虚函数与多态

  • 虚函数
  • 抽象类
    • 纯虚函数
  • 虚析构函数
  • 多态
  • 虚函数的几个问题
  • 纯虚函数和ADT

虚函数

virtual修饰的成员函数就是虚函数,
1.虚函数对类的内存影响:增加一个指针类型大小(32位和64位)
2.无论有多少个虚函数,只增加一个指针类型

虚函数表:指向虚函数的指针(监视的窗口看)
我们自己也可以通过虚函数指针表去访问函数(一般做这样的说数据操作,不写数据类型)

include<iostream>
#include<string>using namespace std;class MM
{
public:virtual void print(){cout << "第一个虚函数" << endl;}virtual void printDate(){cout << "第二个虚函数" << endl;}private:int age;string name;
};
int main()
{cout << sizeof(MM) << endl;system("pause");return 0;
}

抽象类

拥有一个或一个以上的纯虚函数就被叫做抽象类
特点:
1.抽象类不能够创建对象
2.抽象类可以创建对对象指针

纯虚函数

纯虚函数也是一个虚函数,所以也需要virtual来修饰
特点:
1.纯函数没有函数体
所以函数 = 0;

#include<iostream>
#include<string>using namespace std;class MM
{
public:virtual void print() = 0; //纯虚函数private:int age;};
int main()
{//MM mm; //抽象类不能够构造对象MM* pmm = nullptr;return 0;
}

虚析构函数

在析构函数前面加一个virtual

1.当父类指针对子类对象进行初始化的时候,就要用虚析构函数
2.所有析构函数底层解析的话。函数名想相同

include<iostream>
#include<string>using namespace std;class MM
{
public:void print(){cout << "MM" << endl;}~MM(){cout << "MM析构" << endl;}
protected:string M_name;
};class son : public MM
{
public:void print(){cout << "son" << endl;}~son(){cout << "son析构" << endl;}
};int main()
{MM* p = new son; //父类指针,构造子类对象,先构造父类对象,在构造子类的对象delete p;system("pause");return 0;
}

在这里插入图片描述

只调用了父类的析构函数,没有调用子类的析构函数,存在内存的泄露。
所以用父类指针初始化子类的对象,必须使用虚虚构函数

#include<iostream>
#include<string>using namespace std;class MM
{
public:void print(){cout << "MM" << endl;}virtual ~MM(){cout << "MM析构" << endl;}
protected:string M_name;
};class son : public MM
{
public:void print(){cout << "son" << endl;}~son(){cout << "son析构" << endl;}
};int main()
{MM* p = new son; //父类指针,构造子类对象,先构造父类对象,在构造子类的对象delete p;system("pause");return 0;
}

在这里插入图片描述

多态

多态:在继承中,指针的同一行为的不同结果
多态的概念其实并不重要,重要的是,你需要知道,那个对象指针在特定情况调用那个成员。
实现多态的2个条件
1.必须是public继承
2.必须父类存在virtual类型的成员函数,并且子类中存在该函数的同名函数。
3.一定存在对象的引用

#include<iostream>
#include<string>using namespace std;class MM
{
public:void print(){cout << "MM" << endl;}virtual void printDate(){cout << "virtual printDate" << endl;}virtual ~MM(){cout << "MM析构" << endl;}
protected:string M_name;
};class son : public MM
{
public:void print(){cout << "son" << endl;}void printDate(){cout << "printDate" << endl;}~son(){cout << "son析构" << endl;}
};int main()
{//MM* p = new son; //父类指针,构造子类对象,先构造父类对象,在构造子类的对象//delete p;MM* p = new son;p->print();  // 没有virtual,看指针类型,这里调用的是父类的p->printDate();  //有virtual,看对象,这里调用的是son的p = new MM;  //调用MM 的   这就是多态p->print(); //引用的类型也存在多态MM mm;MM& girl = mm;mm.printDate();system("pause");return 0;
}

虚函数的几个问题

不管被继承几次,父类中有的虚函数,依然存在

#include<iostream>using namespace std;class A
{
public:virtual void print(){cout << "A" << endl;}
};class B : public A
{
public:
};class C : public B
{
public:void print(){cout << "C" << endl;}};int main()
{A* p = new C;p->print();system("pause");return 0;
}

在这里插入图片描述

子类实现父类虚函数的同名函数叫做:重写
final :静止重写(子类中不允许存在与之同名的虚函数)
override :强制重写,起说明作用,表示子类当前是方法是重写父类(就是说明父类中一定存在一个同名的虚函数),用于子类实现父类的同名虚函数

#include<iostream>using namespace std;class A
{
public:virtual void print() final   //final:静止重写,子类中不能够存在同名函数{}virtual void printDate(){}};class B : public A
{
public:void printDate() override // 强制重写,起说明作用,表示子类当前是方法是重写父类(就是说明父类中一定存在一个同名的虚函数){}
};
int main()
{system("pause");return 0;
}

纯虚函数和ADT

ADT:抽象数据类型
注意:抽象类本身不能够创建对象,但是抽象类的子类可以创建对象
抽象类,一般用于架构项目,构建好整个项目模块,具体的细致工作,交给子类去实现

采用ADT的方式设计项目,可以把这个模块构建出来,并且测试代码也可以提前完成。

相关文章:

C++虚函数与多态

C虚函数与多态虚函数抽象类纯虚函数虚析构函数多态虚函数的几个问题纯虚函数和ADT虚函数 virtual修饰的成员函数就是虚函数&#xff0c; 1.虚函数对类的内存影响&#xff1a;增加一个指针类型大小&#xff08;32位和64位&#xff09; 2.无论有多少个虚函数&#xff0c;只增加一…...

蓝桥杯Web前端练习-----渐变色背景生成器

介绍 相信做过前端开发的小伙伴们对渐变色在 UI 设计中的流行度一定不陌生&#xff0c;网页上也时常可以看到各类复杂的渐变色生成工具。使用原生的 CSS 变量加一些 JS 函数就能做出一个简单的渐变色背景生成器。 现在渐变色生成器只完成了颜色选取的功能&#xff0c;需要大家…...

Python中的微型巨人-Flask

文章目录前言主要内容优点及特性主要使用创建实例定义路由获取请求定制响应渲染Jinja2模板重定向和反向解析抛出HTTP异常总结更多宝藏前言 &#x1f60e;&#x1f973;&#x1f60e;&#x1f920;&#x1f62e;&#x1f916;&#x1f648;&#x1f4ad;&#x1f373;&#x1f…...

密码学中的承诺

Commitment 概述 密码学承诺是一个涉及两方的二阶段交互协议&#xff0c;双方分别为承诺方和接收方。简述来说&#xff0c;它的功能涵盖不可更改性和确定性。 承诺方发送的消息密文&#xff0c;一旦发出就意味着不会再更改&#xff0c;而接收方收到这个消息可以进行验证结果。…...

redis入门实战一、五种数据结构的基本操作(二)

redis入门实战一、五种数据结构的基本操作【二】 一、String1)、set2)、getset3)、msetnx 给多个元素赋值,原子操作4)、字符串 追加 & 取部分数据5)、数值可以做加减,指定增量大小6)、获取长度7)、 bitmap①、setbit②、bitop 二进制与或运算(效率高)③、bitcou…...

day13 模块和异常捕获总结

day13 模块和异常捕获 一、生成器 &#xff08;一&#xff09;、什么是生成器 1&#xff09;容器&#xff08;是一种可以创建多个数据的容器&#xff09;&#xff0c;生成器中保存的是创建数据的方法&#xff0c;而不是数据本身。2&#xff09;特点&#xff1a; a. 打印生成…...

【Linux】进程优先级 环境变量

进程优先级 环境变量 一、进程优先级1、基本概念2、查看以及修改系统进程的优先级3、一些其他的关于进程优先级的指令和函数调用4、与进程优先级有关的一些进程性质二、环境变量1、基本概念2、和环境变量相关的命令3、Linux中的常见环境变量介绍4、环境变量的组织方式以及在C代…...

UE实现建筑分层抽屉展示效果

文章目录 1.实现目标2.实现过程2.1 基础设置2.2 核心函数3.参考资料1.实现目标 使用时间轴对建筑楼层的位置偏移进行控制,实现分层抽屉的动画展示效果。 2.实现过程 建筑抽屉的实现原理比较简单,即对Actor的位置进行偏移,计算并更新其世界位置即可。这里还是基于ArchVizExp…...

【C语言进阶:刨根究底字符串函数】 strstr 函数

本节重点内容&#xff1a; 深入理解strstr函数的使用学会strstr函数的模拟实现⚡strstr strstr的基本使用&#xff1a; #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include<string.h>int main() {char arr1[] "abcdebcdef";char arr2[] &…...

SpringBoot实战(十二)集成Actuator

目录一、简介二、Maven依赖三、使用入门1.HTTP 方式访问端点2.JMX 方式访问端点3.端点信息整理4.端点的启用与禁用5.端点的公开6.保护 HTTP 端点7.配置 CORS 跨域官方文档&#xff1a; https://docs.spring.io/spring-boot/docs/2.4.5/reference/htmlsingle/#production-ready …...

学习系统编程No.7【进程替换】

引言&#xff1a; 北京时间&#xff1a;2023/3/21/7:17&#xff0c;这篇博客本来昨天晚上就能开始写的&#xff0c;但是由于笔试强训的原因&#xff0c;导致时间用在了做题上&#xff0c;通过快2个小时的垂死挣扎&#xff0c;我充分意识到了自己做题能力的缺陷和运用新知识的缺…...

【3.22】操作系统内存管理(整理)、Java并发

3. 内存管理 为什么要有虚拟内存&#xff1f; 我们想要同时在内存中运行多个程序&#xff0c;就需要把进程所使用的地址隔离&#xff0c;所以使用了虚拟内存。简单来说&#xff0c;虚拟内存地址是程序使用的内存地址。物理内存地址是实际存在硬件里面的地址。 操作系统为每个…...

电脑文件丢失怎么找回来

电脑文件丢失怎么找回来?最近打开电脑时&#xff0c;它启动得很慢。刚刚开始我没有没在意&#xff0c;就重启了当我再次打开电脑时&#xff0c;发现桌面上的文件消失了&#xff0c;面对这种意外情况&#xff0c;有什么办法可以快速找到呢? 电脑文件丢失后&#xff0c;想要找回…...

Python(白银时代)——面向对象

基本概念 面向过程 是早期的一个编程概念&#xff0c;类似函数&#xff0c;但是没有返回值 具体做法&#xff1a; 把完成某个需求的所有步骤&#xff0c;从头到尾 逐步实现 将某些功能独立的代码 封装成一个又一个 函数 然后顺序调用不同的函数 特点&#xff1a; 注重 步骤…...

Python流星雨代码

前言 用Python画场流星雨看看&#xff0c;源码见文末公众号哈。 流星类 def __init__(self): self.r ra.randint(50,100) self.t ra.randint(1,3) self.x ra.randint(-2000,1000) #流星的横坐标 self.y ra.randint(0,500) #流星…...

Java语言-----类与对象的秘密

目录 前言 一、类与对象的介绍 二、类的实例化 三.类与对象的使用方法 3.1对象的初始化 3.2内存显示图 四.this的使用方法 总结 &#x1f63d;个人主页&#xff1a; tq02的博客_CSDN博客-C语言,Java领域博主 &#x1f308;理想目标&#xff1a;努力学习&#xff0c;向Java进…...

大数据处理学习笔记2.1 初识Spark

文章目录零、本节学习目标一、Spark的概述&#xff08;一&#xff09;Spark的组件1、Spark Core2、Spark SQL3、Spark Streaming4、MLlib5、Graph X6、独立调度器、Yarn、Mesos&#xff08;二&#xff09;Spark的发展史1、发展简史2、目前最新版本二、Spark的特点&#xff08;一…...

太强了,英伟达面对ChatGPT还有这一招...

大家好&#xff0c;我是 Jack。 今年可谓是 AI 元年&#xff0c;ChatGPT、AIGC、VITS 都火了一波。 我也先后发布了这几期视频&#xff1a; 这是一个大模型的时代&#xff0c;AI 能在文本、图像、音频等领域大放异彩&#xff0c;得益于大模型。而想要预训练大模型&#xff0c…...

【微服务】—— Nacos注册中心

文章目录一、Nacos 注册中心的设计原理1、数据模型2、数据⼀致性3、负载均衡4、健康检查二、Nacos 注册中心服务数据模型1、服务&#xff08;Service&#xff09;和服务实例&#xff08;Instance&#xff09;1&#xff09;定义服务2&#xff09;服务元数据3&#xff09;定义实例…...

GPT-4是个编程高手,真服了!

上周给大家发了一个GPT-4教数学的介绍&#xff0c;很多人都被震撼了&#xff0c;感觉有可能在教育行业引发革命。它在编程领域表现如何&#xff1f;先不说能否替代程序员&#xff0c;这个还有待更多的测试和反馈&#xff0c;我想先试试它能不能像教数学那样教编程。我找了个Jav…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

Golang——7、包与接口详解

包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...

Python 高效图像帧提取与视频编码:实战指南

Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...

在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/v2@v2.2.0 更换为 go-ansible/@v1.1.7

在 Go 项目中降级 go-ansible 从 v2.2.0 到 v1.1.7 具体步骤&#xff1a; 第一步&#xff1a; 修改 go.mod 文件 // 原 v2 版本声明 require github.com/apenella/go-ansible/v2 v2.2.0 替换为&#xff1a; // 改为 v…...

拟合问题处理

在机器学习中&#xff0c;核心任务通常围绕模型训练和性能提升展开&#xff0c;但你提到的 “优化训练数据解决过拟合” 和 “提升泛化性能解决欠拟合” 需要结合更准确的概念进行梳理。以下是对机器学习核心任务的系统复习和修正&#xff1a; 一、机器学习的核心任务框架 机…...