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

一文带你掌握C++虚函数·和多态

9. C++虚函数与多态

虚函数

virtual修饰的成员函数就是虚函数

  • 虚函数对类的内存影响:需要增加一个指针类型的内存大小
  • 无论多少虚函数,只会增加一个指针类型的内存大小
  • 虚函数表的概念: 指向虚函数的指针

我们自己也可以通过虚函数表指针去访问函数(一般做这样的操作不写数据类型)

#include <iostream>
#include <string>
using namespace std;
class MM 
{
public:virtual void print() 				//1.会写{cout << "第一个虚函数" << endl;}virtual void printData() {cout << "第二个虚函数" << endl;}
protected:};
int main() 
{cout << sizeof(MM) << endl;   	//2.对类内存影响MM mm;mm.print();mm.printData();//了解一下.32位没问题,64位 vs2022 问题int** pObject = (int **)(&mm);typedef void(*PF)();PF pf = (PF)pObject[0][0];pf();						//调用第一个虚函数pf = (PF)pObject[0][1];pf();						//调用第二个虚函数return 0;
}

纯虚函数

具有一个或者多个纯虚函数的类型称之为抽象类,抽象类特性:

  • 抽象类不能创建对象
  • 抽象类可以创建对象指针

纯虚函数也是一个虚函数,所以也需要virtual修饰,纯虚函数是没有函数体,函数=0;

#include <iostream>
using namespace std;
//抽象类
class MM 
{
public://纯虚函数virtual void print() = 0;
protected:string name;
};
int main() 
{//MM object;   抽象类不能构建对象MM* pMM = nullptr;return 0;
}

虚析构函数

virtual修饰的析构函数 就是虚析构函数

  • 当父类指针被子类对象初始化的时候需要用虚析构函数
  • 所有析构函数底层解析其实函数名相同

#include <iostream>
#include <string>
using namespace std;
class MM 
{
public:void print() {cout << "MM::print" << endl;}virtual ~MM()					//虚析构函数{cout << "~MM" << endl;}
};
class Son :public MM 
{
public:void print() {cout << "Son::print" << endl;}~Son() {cout << "~Son" << endl;}
};int main() 
{MM* pMM = new Son;   //构造子类对象,必须构造父类对象在构造自身pMM->print();		 //MM看类型delete pMM;pMM = nullptr;return 0;
}

虚函数和多态

多态的概念并不重要,重要的是需要知道那个对象指针在特定情况调用那个成员才是重要

多态概念: 指在继承中指针的同一行为的不同结果,举个栗子(男生和女生上厕所,都是上厕所的行为,男生站着,女生蹲着)

实现多态的两个前提条件:

  • 必须是public继承
  • 必须父类存在virtual类型的成员函数,并且子类中存在该函数的同名函数
  • 一定存在指针的引用
#include <iostream>
#include <string>
using namespace std;
class MM
{
public:void print(){cout << "MM::print" << endl;}virtual void printData() {cout << "MM virtual printData" << endl;}virtual ~MM()					//虚析构函数{cout << "~MM" << endl;}
};
class Son :public MM
{
public:void print(){cout << "Son::print" << endl;}void printData() {cout << "Son printData" << endl;}~Son(){cout << "~Son" << endl;}
};
int main() 
{//正常对象的访问,不存在多态//都是就近原则cout << "正常对象访问" << endl;MM mmobject;mmobject.print();mmobject.printData();Son sonobject;sonobject.print();sonobject.printData();//正常的指针访问cout << "正常指针访问" << endl;MM* pMM = new MM;pMM->print();pMM->printData();Son* pSon = new Son;pSon->print();pSon->printData();//非正常的初始化//父类指针被子类初始化cout << "不正常的指针赋值" << endl;MM* pObject = new Son;pObject->print();				//没有virutal 看指针类型 调用MM::printpObject->printData();			//有virtual 看对象 调用Son::printDatapObject = new MM;pObject->printData();			//调用MM中cout << "引用类型" << endl;MM& girl = sonobject;girl.print();girl.printData();return 0;
}

虚函数在继承特殊现象

#include <iostream>
#include <string>
using namespace std;
class A
{
public:virtual void print(){cout << "A" << endl;}virtual void printData() final   //禁止子类重写方法{cout << "A" << endl;}
};//final: 父类中用来禁止子类重写同名方法
//override: 强制重写,起说明作用,表示当前子类当前方法是重写父类
class B :public A 
{
public://重写:子类实现父类虚函数的同名函数void print() override{cout << "B" << endl;}//void printData(){}  //final禁止重写
};
class C :public B 
{
public:void print() {cout << "C" << endl;}
};
int main() 
{B* pb = new C;pb->print();			//调用C::printpb = new B;pb->print();			//调用B::printreturn 0;
}

纯虚函数和ADT

ADT: 抽象数据类型

抽象类本身不能创建对象,但是子类如果重写类父类中纯虚函数,子类是可以被允许创建对象

抽象类一般用于架构项目,构建好整个项目模块,具体细致工作可以交给子类去实现

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

#include <iostream>
using namespace std;//抽象产品类
class AbstractProduct 
{
public:virtual void printProduct() = 0;
};
//抽象系统类---ADT
//析构函数一定写虚析构函数
class AbstractSystem 
{
public:~AbstractSystem() {}virtual void insertData(AbstractProduct* product) = 0;virtual void printData()const = 0;virtual int size() const = 0;virtual bool empty() const = 0;
};class ArraySystem :public AbstractSystem 
{
public:void insertData(AbstractProduct* product) {}void printData()const {}int size() const {return 0;}bool empty() const {return 0;}
};
class ListSystem :public AbstractSystem
{
public:void insertData(AbstractProduct* product){}void printData()const{}int size() const{return 0;}bool empty() const{return 0;}
};
int main() 
{AbstractSystem* p =new  ArraySystem;p->printData();//UI中用的比较多//MFC --->不需要自己创建,只需要重写一个,构建对象即可p = new ListSystem;p->printData();return 0;
}

相关文章:

一文带你掌握C++虚函数·和多态

9. C虚函数与多态 虚函数 virtual修饰的成员函数就是虚函数 虚函数对类的内存影响:需要增加一个指针类型的内存大小无论多少虚函数&#xff0c;只会增加一个指针类型的内存大小虚函数表的概念: 指向虚函数的指针 我们自己也可以通过虚函数表指针去访问函数(一般做这样的操作…...

OpenCV 4.10 + OpenCV_contrib配置教程 仅供参考

参考&#xff1a;https://blog.csdn.net/qq_27278957/article/details/108224325 https://blog.csdn.net/weixin_43763292/article/details/130232863 OpenCV&#xff1a;https://github.com/opencv/opencv/releases/tag/4.10.0 OpcenCV_contrib: https://github.com/opencv/o…...

ClkLog:开源用户行为分析框架,让数据分析更轻松

ClkLog&#xff1a;开源用户行为分析框架&#xff0c;让数据分析更轻松 在数据驱动的时代&#xff0c;找到一个好用的用户行为分析工具真是难上加难。但是今天你有福了&#xff0c;开源免费的 ClkLog 就是你的不二选择&#xff01;本文将为你详细介绍 ClkLog 的功能特点、技术架…...

Spring源码学习笔记之@Async源码

文章目录 一、简介二、异步任务Async的使用方法2.1、第一步、配置类上加EnableAsync注解2.2、第二步、自定义线程池2.2.1、方法一、不配置自定义线程池使用默认线程池2.2.2、方法二、使用AsyncConfigurer指定线程池2.2.3、方法三、使用自定义的线程池Excutor2.2.4、方法四、使用…...

面试题:如何验证代码的可靠性

代码结构上的&#xff1a; 1 可扩展性 是否否和开闭原则 2 性能&#xff0c;数据结构用的是否合理&#xff0c;算法等是否效率高。 3 安全性 是否存在潜在的安全 整数溢出 SQL注入 等 4 代码复杂度 圈负杂度 if嵌套深度 函数长度等 5 函数变量的命名是否具有自解释性 1. …...

前端开发的十字路口,薪的出口会是AI吗?

前言 在数字化转型的浪潮中&#xff0c;前端开发一直扮演着至关重要的角色&#xff0c;它连接着用户与产品之间的桥梁。然而&#xff0c;随着技术的不断进步和社会经济环境的变化&#xff0c;前端开发领域也面临着前所未有的挑战和机遇。 前端开发的困境 前端开发领域的竞争…...

pdf太大怎么压缩大小?这几种压缩方法操作起来很简单!

pdf太大怎么压缩大小&#xff1f;在数字化洪流席卷的当下&#xff0c;PDF文件的“臃肿”难题如同巨石般横亘于高效办公之路&#xff0c;它们不仅贪婪地吞噬着宝贵的存储空间&#xff0c;更如沉重的枷锁&#xff0c;拖曳着我们的工作进度&#xff0c;步入迟缓之境&#xff0c;试…...

leetcode-148. 排序链表

题目描述 给你链表的头结点 head &#xff0c;请将其按 升序 排列并返回 排序后的链表 。 示例 1&#xff1a; 输入&#xff1a;head [4,2,1,3] 输出&#xff1a;[1,2,3,4]示例 2&#xff1a; 输入&#xff1a;head [-1,5,3,4,0] 输出&#xff1a;[-1,0,3,4,5]示例 3&#x…...

16 html网页服务和nginx服务

第十六次7.29 1.静态页面 1安装httpd [rootweb ~]# yum -y install httpd 2.真机访问页面 [rootweb html]# echo "静态html文件" > index.html 传入照片再次访问 静态资源&#xff0c;根据开发着保存在项目资源目录中的路径访问静态页面的资源 2.Apache 1.安…...

C语言:扫雷游戏实现

一、扫雷游戏的分析和设计 扫雷游戏想必大家都玩过吧&#xff0c;初级的玩法是在一个9*9的棋盘上找到没有雷的格子&#xff0c;而今天我们就要做的就是9*9扫雷游戏的实现。 1、游戏功能和规则 使用控制台实现经典的扫雷游戏游戏可以通过菜单实现继续玩或者退出游戏扫雷的棋盘…...

算法入门:Java实现排序、查找算法

链接&#xff1a;算法入门&#xff1a;Java实现排序、查找算法 (qq.com) 冒泡/选择/插入/希尔排序代码 (qq.com) 快排/归并/堆排/基数排序代码 (qq.com)...

【初阶数据结构篇】顺序表的实现(赋源码)

文章目录 本篇代码位置顺序表和链表1.线性表2.顺序表2.1 概念与结构2.2分类2.2.1 静态顺序表2.2.2 动态顺序表 2.3 动态顺序表的实现2.3.1动态顺序表的初始化和销毁及打印2.3.2动态顺序表的插入动态顺序表的尾插动态顺序表的头插动态顺序表的在指定位置插入数据 2.3.3动态顺序表…...

移动式气象站:便携科技的天气守望者

在科技日新月异的今天&#xff0c;我们身边的许多设备都在向着更加智能化、便携化的方向发展。而在气象观测领域&#xff0c;移动式气象站的出现&#xff0c;不仅改变了传统气象观测的固有模式&#xff0c;更以其灵活性和实时性&#xff0c;在气象监测、灾害预警等领域发挥着越…...

软件测试必备 - 14个接口与自动化测试练习网站

随着互联网和移动应用的快速发展,接口和自动化测试的重要性日益凸显。越来越多的企业开始重视API测试,因为它不仅能提升开发效率,还能确保系统的稳定性和安全性。这些练习网站为测试人员提供了宝贵的资源,帮助他们掌握必要的技能,应对日益复杂的测试需求。 在软件测试的世…...

基于 HTML+ECharts 实现的数据可视化大屏案例(含源码)

数据可视化大屏案例&#xff1a;基于 HTML 和 ECharts 的实现 数据可视化已成为企业决策和业务分析的重要工具。通过直观、动态的图表展示&#xff0c;数据可视化大屏能够帮助用户快速理解复杂的数据关系&#xff0c;发现潜在的业务趋势。本文将介绍如何利用 HTML 和 ECharts 实…...

vardaccico前端私有库

vardacico docker pull verdaccio/verdaccio:4 docker run -it --rm --name verdaccio -p 4873:4873 verdaccio/verdaccio Docker | Verdaccio 拷贝docker中的配置到宿主机 进入docker内部 docker exec -it verdaccio /bin/sh 进入到指定目录 cd /verdaccio 开始拷贝到指定目…...

先用先发!小样本故障诊断新思路!Transformer-SVM组合模型多特征分类预测/故障诊断(Matlab)

先用先发&#xff01;小样本故障诊断新思路&#xff01;Transformer-SVM组合模型多特征分类预测/故障诊断&#xff08;Matlab&#xff09; 目录 先用先发&#xff01;小样本故障诊断新思路&#xff01;Transformer-SVM组合模型多特征分类预测/故障诊断&#xff08;Matlab&#…...

学习大数据DAY26 简单数据清洗练习和 Shell 脚本中的数据库编程

目录 上机练习 14 mysql 命令 sql 语句实现步骤 shell 脚本导入 csv 格式文件到 mysql 数据库 secure-file-priv 特性 把文件拷贝到 mysql 指定目录下 上机练习 15 mysqldump 命令 上机练习 16 上机练习 14 运用上一节课学的 Shell 工具完成 1. 清洗数据《infotest.t…...

开发业务(3)——swoole和聊天室入门开发

在普通的PHP代码里面&#xff0c;我们不需要考虑性能和异步问题&#xff0c;包括不限于我们想要使用php搭建一个http服务器&#xff08;在node/python/go里面都有http模块&#xff0c;但是PHP没有这种功能&#xff09;。而同样的原因&#xff0c;很难实现php游戏的开发&#xf…...

Linux系统服务——【web,http协议,apache服务和nginx服务】(sixteen day)

一、web基础以及http协议 1、web基本概念和常识 前端开发一般用uniapp. 1、Web:为用户提供的一种在互联网上浏览信息的服务&#xff0c;Web 服务是动态的、可交互的、跨平台的和图形化的。 2、Web 服务为用户提供各种互联网服务&#xff0c;这些服务包括信息浏览服务&#xf…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表

1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...