多态--下
文章目录
- 概念
- 多态如何实现的指向谁调谁?
- 例子
- 分析
- 含有虚函数类的大小是多少?
- 虚函数地址
- 虚表地址
- 多继承的子类的大小怎么计算?
- 练习题
- 虚函数和虚继承
概念
优先使用组合、而不是继承;
继承会破坏父类的封装、因为子类也可以调用到父类的函数;
子类必须实现父类的纯虚函数;
内联函数没有地址,他是直接在定义的地方展开。所以不能是虚函数、虚函数是要有地址的;
虚函数不能是static函数,因为没有this指针、等于说是全局的,虚表要的是对象里面的;
普通函数继承是实现继承,就是不去重写父类的函数体,直接用的;虚函数的继承目的就是要重写这个函数体,自改成自己想要的;
虚函数在编译阶段就生成了,并且存在代码段;
析构函数最好写成多态。多态就是指向谁调谁,这样子类就可以调用自己的析构函数
构造函数不能写成多态;因为对象中的虚表指针实在初始化列表时开始初始化的;
多态如何实现的指向谁调谁?
虚函数的地址存在虚函数表中,通过虚函数表来调用虚函数;
同类型的对象共用一个虚表;
子类不重写父类的虚函数,也是和父类共用同一张虚表;重写就不会共用虚表
例子
#define _CRT_SECURE_NO_WARNINGS#include <iostream>
using namespace std;class person
{
public:virtual void BuyTicket(){cout << "成人票" << endl;}
};class student : public person
{
public:virtual void BuyTicket(){cout << "学生票" << endl;}
};void buy(person& b)
{b.BuyTicket();
}int main()
{student s;person p;buy(s);buy(p);return 0;
}
分析
1、子类继承后,虚函数表是一样的,重写后就把虚函数表copy出来换一个地址,把新的内容覆盖了;

2、调用时传过去的参数累心是谁的就指向谁的虚函数表,s是student类型那就是用student里面的函数;

2、子类虚函数不重写会怎样
如果不重写,那父级和子级虚函数表的地址是相同的

含有虚函数类的大小是多少?
普通函数不占空间,虚函数有个指针、所以站指针的大小空间,32位的4字节、64位的8字节;
在类里面:虚函数占一个指针的大小,不管有多少个虚函数就只占一个指针的大小;对象里面只是存了一个指针指向这个虚表
虚表的大小才要看有几个虚函数;
多继承的子类,继承了几个父类就有几个父类的指针大小
如下就一个虚函数64位

计算方法和结构体其实一样,内存对齐
加了一个int变量,理应8+4 = 12,但是最小对齐数为8,类的大小是其成员最小对齐数的整数倍;所以是16;

虚函数地址
#define _CRT_SECURE_NO_WARNINGS#include <iostream>
using namespace std;class person
{
public:virtual void BuyTicket(){cout << "成人票" << endl;}
private:int a;
};class student : public person
{
public:virtual void BuyTicket(){cout << "学生票" << endl;}
};void buy(person& b)
{b.BuyTicket();
}class base
{
public:virtual void func1(){cout << "base::func1" << endl;}
private:int _b = 1;
};void func()
{person b1;printf("vftptr:%p\n", *(int*) & b1);int i = 0;int* p1 = &i;int* p2 = new int;const char* p3 = "sad";printf("栈变量:%p\n", p1);printf("堆变量:%p\n", p2);printf("代码段常量:%p\n", p3);printf("代码段函数地址:%p\n", &base::func1);}int main()
{student s;person p;buy(s);buy(p);int size = sizeof(s);cout << size << endl;func();return 0;
}
问题:虚函数存在哪?虚函数表存在哪?
答:虚函数和普通函数都存在代码段、虚函数表也存在代码段

普通的函数、函数名就是地址(首地址)
成员函数的地址要加取地址符号&,以及要指定属于哪个类,也就是这样 &类名::函数名
虚表地址
class Base
{
public:virtual void fuc1(){cout << "fuc1" << endl;}virtual void fuc2(){cout << "fuc2" << endl;}
private:int a;
};class derive : public Base
{
public:virtual void fuc1(){ cout << "fuc1111" << endl; }virtual void fuc3(){cout << "fuc3" << endl;}
};typedef void(*VF_PTR)();//函数指针类型怎么写的
void PrintVFTable(VF_PTR* pTable)
{for(size_t i = 0; pTable[i] != 0; ++i){printf("vfTable[%d]:%p->", i, pTable[i]);VF_PTR f = pTable[i];f();//运行函数}cout << endl;
}int main()
{//student s;//person p;//buy(s);//buy(p);//int size = sizeof(s);//cout << size << endl;//func();derive a;Base b;PrintVFTable((VF_PTR*)(*(int*)&b));PrintVFTable((VF_PTR*)(*(int*)&a));return 0;
}
父类上面两行、子类为下面三行;
子类fuc1重写过了虚表地址就变了,没写fuc2但是继承了fuc2的虚表地址;

强转两次,(int*)是要取前4个字符,(VF_PTR*)强转函数指针

函数指针怎么写 void(*)()
type void(*a)(),这个a就代表函数指针了
多继承的子类的大小怎么计算?
继承几个父类就含有几个指针;
class Base1
{
public:virtual void fuc1() { cout << "b1:fuc1" << endl; }virtual void fuc2() { cout << "b1:fuc2" << endl; }
private:int a1;
};class Base2
{
public:virtual void fuc1() { cout << "b2:fuc1" << endl; }virtual void fuc2() { cout << "b2:fuc2" << endl; }
private:int a2;
};class derive2 : public Base1, public Base2
{virtual void fuc1() { cout << "b2:fuc1" << endl; }virtual void fuc3() { cout << "b2:fuc2" << endl; }private:int a3;
};int main()
{//student s;//person p;//buy(s);//buy(p);//int size = sizeof(s);//cout << size << endl;//func();//derive a;//Base b;//PrintVFTable((VF_PTR*)(*(int*)&b));//PrintVFTable((VF_PTR*)(*(int*)&a));cout << sizeof(derive2) << endl;derive2 a1;PrintVFTable((VF_PTR*)(*(int*)&a1));PrintVFTable((VF_PTR*)(*(int*)((char*)&a1 + sizeof(Base1))));return 0;
}

继承两个父类,两个指针的大小;
不同父类的虚表继承后不会共用;
derive2成员函数fuc3的虚表和Base1的虚表共用了,随机共用一个父类的虚表;
练习题
1、

2、
类中就只有变量、按顺序往下排;
p3是指向整块区域,所以首地址也是b1存的首地址;
p1也是b1存的首地址;
p2是b2的首地址;
所以选c;

虚函数和虚继承

是两个完全不同的概念;
用的都是virtual;
虚继承

菱形继承时,B、C继承A,D继承BC;

如上图使用虚继承,就会把公共的变量_a,放到一个地址上;
如果不用虚继承的话,就会有三个_a的地址;造成数据的冗余性;
二义性也是不用虚继承造成的,就是再回去找_a时,有很多_a;
相关文章:
多态--下
文章目录 概念多态如何实现的指向谁调谁?例子分析 含有虚函数类的大小是多少?虚函数地址虚表地址多继承的子类的大小怎么计算?练习题虚函数和虚继承 概念 优先使用组合、而不是继承; 继承会破坏父类的封装、因为子类也可以调用到父类的函数;…...
备考ICA----Istio实验16---HTTP流量授权
备考ICA----Istio实验16—HTTP流量授权 1. 环境准备 kubectl apply -f istio/samples/bookinfo/platform/kube/bookinfo.yaml kubectl apply -f istio/samples/bookinfo/networking/bookinfo-gateway.yaml访问测试 curl -I http://192.168.126.220/productpage2. 开启mtls …...
STM32-02基于HAL库(CubeMX+MDK+Proteus)GPIO输出案例(LED流水灯)
文章目录 一、功能需求分析二、Proteus绘制电路原理图三、STMCubeMX 配置引脚及模式,生成代码四、MDK打开生成项目,编写HAL库的GPIO输出代码五、运行仿真程序,调试代码 一、功能需求分析 在完成开发环境搭建之后,开始使用STM32GP…...
华为审核被拒提示: 您的应用存在(最近任务列表隐藏风险活动)的行为,不符合华为应用市场审核标准
应用审核意见: 您的应用存在(最近任务列表隐藏风险活动)的行为,不符合华为应用市场审核标准。 修改建议:请参考测试结果进行修改。 请参考《审核指南》第2.19相关审核要求:https://developer.huawei.com/c…...
数论与线性代数——整除分块【数论分块】的【运用】【思考】【讲解】【证明(作者自己证的QWQ)】
文章目录 整除分块的思考与运用整除分块的时间复杂度证明 & 分块数量整除分块的公式 & 公式证明公式证明 代码code↓ 整除分块的思考与运用 整除分块是为了解决一个整数求和问题 题目的问题为: ∑ i 1 n ⌊ n i ⌋ \sum_{i1}^{n} \left \lfloor \frac{n}{…...
Linux系统下安装jdk与tomcat【linux】
一、yum介绍 linux下的jdk安装以及环境配置,有两种常用方法: 1.使用yum一键安装。 2.手动安装,在Oracle官网下载好需要的jdk版本,上传解压并配置环境。 这里介绍第一种方法,在此之前简单了解下yum。 yum 介绍 yum&…...
matlab实现决策树可视化——信息增益、C4.5、基尼指数
代码:https://download.csdn.net/download/boyas/89074326...
如何使用Python进行网络编程和套接字通信?
如何使用Python进行网络编程和套接字通信? Python作为一种通用编程语言,具有强大的网络编程能力。它提供了丰富的库和工具,使得开发者可以轻松地实现网络编程和套接字通信。下面将详细介绍如何使用Python进行网络编程和套接字通信。 一、网…...
nodeJs 实现视频的转换(超详细教程)
前段时间拿到一个视频是4k的,没法播放,于是通过 node.js 和 ffmpeg 实现了视频的转换。在win10 系统下实现。 所需工具 node 16.19 直接安装 ffmpeg-5.1.1-essentials_build 解压后重名 ffmpeg 放到C盘 然后配置下环境变量 Git-2.42.0.2-64-bit 直接…...
Transformer - model architecture
Transformer - model architecture flyfish Transformer总体架构可分为四个部分: 输⼊部分 输出部分 编码器部分 解码器部分 输入部分 输出部分 输⼊部分包含: 源嵌⼊层和位置编码 ⽬标嵌⼊层和位置编码 输出部分包含: 线性层 softmax处理器 左侧编码器部分和右侧解码器部…...
Zookeeper学习一
初识 Zookeeper Zookeeper 是 Apache Hadoop 项目下的一个子项目,是一个树形目录服务(B树)。 Zookeeper 翻译过来就是 动物园管理员,他是用来管 Hadoop(大象)、Hive(蜜蜂)、Pig(小 猪)的管理员。简称zk …...
SAR教程系列7——在cadence中用Spectrum工具FFT仿真ADC的ENOB、SNR等动态性能指标
首先在仿真之前,你得有一个ADC。然后是思考如何仿真的问题,如何加激励,如何使用相关工具查看仿真结果。假定你有一个可以仿真的ADC,大致经过下列步骤可以得到ADC的相关动态性能指标。 第一步:在ADC后面接一个理想的DA…...
攻防世界:mfw[WriteUP]
根据题目提示考虑是git库泄露 这里在地址栏后加.git也可以验证是git库泄露 使用GitHack工具对git库进行恢复重建 在templates目录下存在flag.php文件,但里面并没有flag 有内容的只有主目录下的index.php index.php源码: <?phpif (isset($_GET[page…...
mysq性能优化-my.cnf配置文件参数调整
MySQL 优化配置文件(my.cnf 或 my.ini)是调整 MySQL 服务器性能的重要手段之一。以下是一些常见的场景,可以通过调整配置文件参数值来优化 MySQL: 1. **提高并发处理能力**: - innodb_buffer_pool_size:增…...
ddres( ) 组站星双差方程和设计矩阵
1 ddres( )参数介绍 rtklib中进行的单频解算 双差观测值,单差的模糊度 单频点双差 DD (double-differenced) phase/code residuals ------------------------------ x 模糊度 P 方差-协方差阵 sat 共识卫星列表 ns 共识卫星数量 y…...
【OpenCV】图像像素的遍历
1 前言 介绍两种遍历像素的方法(非指针、指针)。注意:.at() .ptr()的作用、用法。相关API: Mat对象.ptr() Mat对象.at() 2 代码及内容 #include "iostream" #include "opencv2/opencv.hpp"using namespac…...
(超简单)构建高可用网络应用:使用Nginx进行负载均衡与健康检查
当构建高可用的网络应用时,负载均衡是至关重要的技术之一。Nginx 是一个强大的开源反向代理服务器,提供了丰富的负载均衡功能,包括负载均衡算法和健康检查。在本篇博客中,我们将讨论如何使用 Nginx 进行负载均衡,并结合…...
华为OD面试手撕算法-合并排序数组
题目描述 本题是leetcode一道简单题:合并两个有序数组,但是对于时间和空间复杂度面试官明确给出了限制。 // 给定两个排序后的数组 A 和 B,其中 A 的末端有足够的缓冲空间容纳 B。 编写一个方法,将 B 合并入 A 并排序。 // 初始化…...
云智慧发布对象关系型数据库CloudPanguDB,打破传统技术壁垒
近日,云智慧推出关系型数据库CloudPanguDB(中文名称:盘古数据库),旨在通过高兼容性能和创新技术架构,降低企业项目整体运营成本。 无论是处理海量复杂数据,还是构建清晰有序的数据结构关系&…...
6.8物联网RK3399项目开发实录-驱动开发之RTC实时时钟的使用(wulianjishu666)
90款行业常用传感器单片机程序及资料【stm32,stc89c52,arduino适用】 链接:https://pan.baidu.com/s/1M3u8lcznKuXfN8NRoLYtTA?pwdc53f RTC 使用 简介 AIO-3399J 开发板上有 一个集成于 RK808 上的RTC(Real Time Clock),主要功能有时钟,…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...
跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
快刀集(1): 一刀斩断视频片头广告
一刀流:用一个简单脚本,秒杀视频片头广告,还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农,平时写代码之余看看电影、补补片,是再正常不过的事。 电影嘛,要沉浸,…...
Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...
