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

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

Python中的微型巨人-Flask
文章目录前言主要内容优点及特性主要使用创建实例定义路由获取请求定制响应渲染Jinja2模板重定向和反向解析抛出HTTP异常总结更多宝藏前言 😎🥳😎🤠😮🤖🙈💭🍳…...

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

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

day13 模块和异常捕获总结
day13 模块和异常捕获 一、生成器 (一)、什么是生成器 1)容器(是一种可以创建多个数据的容器),生成器中保存的是创建数据的方法,而不是数据本身。2)特点: 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 函数
本节重点内容: 深入理解strstr函数的使用学会strstr函数的模拟实现⚡strstr strstr的基本使用: #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 跨域官方文档: https://docs.spring.io/spring-boot/docs/2.4.5/reference/htmlsingle/#production-ready …...

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

【3.22】操作系统内存管理(整理)、Java并发
3. 内存管理 为什么要有虚拟内存? 我们想要同时在内存中运行多个程序,就需要把进程所使用的地址隔离,所以使用了虚拟内存。简单来说,虚拟内存地址是程序使用的内存地址。物理内存地址是实际存在硬件里面的地址。 操作系统为每个…...

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

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

Python流星雨代码
前言 用Python画场流星雨看看,源码见文末公众号哈。 流星类 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的使用方法 总结 😽个人主页: tq02的博客_CSDN博客-C语言,Java领域博主 🌈理想目标:努力学习,向Java进…...

大数据处理学习笔记2.1 初识Spark
文章目录零、本节学习目标一、Spark的概述(一)Spark的组件1、Spark Core2、Spark SQL3、Spark Streaming4、MLlib5、Graph X6、独立调度器、Yarn、Mesos(二)Spark的发展史1、发展简史2、目前最新版本二、Spark的特点(一…...

太强了,英伟达面对ChatGPT还有这一招...
大家好,我是 Jack。 今年可谓是 AI 元年,ChatGPT、AIGC、VITS 都火了一波。 我也先后发布了这几期视频: 这是一个大模型的时代,AI 能在文本、图像、音频等领域大放异彩,得益于大模型。而想要预训练大模型,…...

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

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

基于深度学习的车型识别系统(Python+清新界面+数据集)
摘要:基于深度学习的车型识别系统用于识别不同类型的车辆,应用YOLO V5算法根据不同尺寸大小区分和检测车辆,并统计各类型数量以辅助智能交通管理。本文详细介绍车型识别系统,在介绍算法原理的同时,给出Python的实现代码…...

【蓝桥杯C++】3月21日刷题集训ABC-附百分代码,一目了然
目录 刷题集训 A Day 1 成绩分析 Day 1 饮料换购 刷题集训 B Day 1 分巧克力 Day 1 递增三元组 Day 1 小明的衣服 刷题集训 C Day 1 数字三角形 Day 1 跳跃 Day 1 蓝太子序列 刷题集训 A Day 1 成绩分析 题目描述 小蓝给学生…...

HBase高手之路4-Shell操作
文章目录HBase高手之路3—HBase的shell操作一、hbase的shell命令汇总二、需求三、表的操作1.进入shell命令行2.创建表3.查看表的定义4.列出所有的表5.删除表1)禁用表2)启用表3)删除表四、数据的操作1.添加数…...

聊聊SQL审计功能
什么是sql审计SQL审计是指对SQL语句的执行情况进行记录和追踪,包括SQL语句的执行时间、执行次数、执行结果等信息。通过SQL审计,可以对数据库的使用情况进行监控和管理,包括对SQL注入、非法访问、数据泄露等安全问题的检测和防范,…...

Markdown常用语法(字体颜色)
一些不错的帖子 写CSDN博客时,调节字体大小、颜色及其他样式的常用操作方法 设置字体颜色 使用<font>标记: 这是红色字体:<font colorred>我是红色的字体</font>显示效果如下: 这是红色字体:我是…...

I2C模块理解
I2C模块理解 文章目录I2C模块理解1.配置I2C2.信号3.数据传输3.1主机发送3.2主机接收3.3从机发送3.4从机接收4.中断传输5.Aardvark1.配置I2C I2C的特征 只需要两条公共总线(线)即可控制I2C网络上的任何设备无需像UART通信那样事先约定数据传输速率。因此…...

手把手教你使用--常用模块--HC05蓝牙模块,无线蓝牙串口透传模块,(实例:手机蓝牙控制STM32单片机点亮LED灯)
最近在学STM32,基本的学完了,想学几个模块来巩固一下知识,就想到了蓝牙模块。玩啥好难过有很多博客教怎么连的,但自己看起来还是有点糊涂。模块的原理和知识点我就不讲解了,这里我主要手把手记录一下我是如何对蓝牙模块…...

MyBatis高频面试题
目录 1、Mybatis中#和$的区别 2、Mybatis的编程步骤是什么样的 3...

Redis基础篇
redis的三大特点: 支持多数据类型,支持持久化,单线程 多路IO复用 对键操作的命令: keys * 查看当前库所有key exists key 判断key是否存在 del key 删除 unlink key 非阻塞删除,异步删除 expire key …...

unity的C#学习——静态常量和动态常量的定义与使用
定义常量 在C#中,常量是一种不可改变的量,一旦被定义,其值就不能被修改。C#中有两种类型的常量,静态常量和动态常量。 1、静态常量的定义 静态常量是在编译时就已经确定其值的常量,使用const关键字定义。由于在编译…...