C++虚函数产生的多态

news2024/11/8 4:45:02

C++虚函数产生的多态

1、先看下面代码,参考施雷老师课堂笔记

#include<iostream>
#include<vector>
#include <algorithm>
#include <functional>
using namespace std;


/*
虚函数,静态绑定和动态绑定

覆盖:
基类和派生类的方法,返回值、函数名以及参数列表都相同,而且基类的方法是虚函数,
那么派生类的方法就自动处理成虚函数,它们之间成为覆盖关系

一个类添加了虚函数,对这个类有什么影响?
总结一:
一个类里面定义了虚函数,那么编译阶段,编译器给这个类类型产生一个唯一的vftable虚函数
表,虚函数表中主要存储的内容就是RTTI指针和虚函数的地址。当程序运行时,每一张虚函数表
都会加载到内存的.rodata区。

总结二:
一个类里面定义了函数数,那么这个类定义的对象,其运行时,内存中开始部分,多存储一个
vfptr虚函数指针,指向相应类型的虚函数表vftable。一个类型定义的n个对象,它们的额vfptr
指向的都是同一张虚函数表

总结三:
一个类里面虚函数的个数,不影响对象内存大小(vfptr),影响的是虚函数表的大小
*/
class Base
{
public:
	Base(int data = 10) :ma(data) {}
	// 虚函数
	virtual void show() { cout << "Base::show()" << endl; }
	// 虚函数
	virtual void show(int) { cout << "Base::show(int)" << endl; }
protected:
	int ma;
};
class Derive : public Base
{
public:
	Derive(int data = 20) :Base(data), mb(data) {}
	/*
	总结四:
	如果派生类中的方法,和基类继承来的某个方法,返回值、函数名、参数列表都相同,
	而且基类的方法是virtual虚函数,那么派生类的这个方法,自动处理成虚函数
	重写《=》覆盖   
	*/
	void show() { cout << "Derive::show()" << endl; }
private:
	int mb;
};
int main()
{
	Derive d(50);
	Base *pb = &d;

	/*	pb->Base Base::show 如果发现show是普通函数,就进行静态绑定 
											call Base::show
	pb->Base Base::show 如果发现show是虚函数,就进行动态绑定了
	mov eax, dword ptr[pb]
	mov ecx, dword ptr[eax]
	call ecx(虚函数的地址) 动态(运行时期)的绑定(函数的调用)
	*/
	pb->show(); //静态(编译时期)的绑定(函数的调用)call  Base::show (01612DAh)
	
	/*
	Base::show(int) 是一个虚函数,此时就得动态绑定了
	mov eax, dword ptr[pb]
	mov ecx, dword ptr[eax]
	call ecx(虚函数的地址) 动态(运行时期)的绑定(函数的调用)
	*/
	pb->show(10); //静态绑定 call  Base::show (01612B2h)

	cout << sizeof(Base) << endl; // 4 8
	cout << sizeof(Derive) << endl; // 8 12

	cout << typeid(pb).name() << endl; // class Base*
	/*
	pb的类型:Base -> 有没有虚函数
	如果Base没有虚函数,*pb识别的就是编译时期的类型  *pb <=> Base类型
	如果Base有虚函数,*pb识别的就是运行时期的类型 RTTI类型
	pb->d(vfptr)->Derive vftable  class Derive 
	*/ 
	cout << typeid(*pb).name() << endl; // class Base  class Derive 
	/*
	Base的两个show函数都是普通的函数
	Base::show()
	Base::show(int)
	4
	8
	class Base *
	class Base
	*/

	/*
	给Base的两个show方法定义成virtual虚函数了
	Derive::show()
	Base::show(int)
	8
	12
	class Base *
	class Derive
	*/

	return 0;
}

在这里插入图片描述

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

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

相关文章

Vue3 实现 clipboard 复制功能

一个很小的交互功能&#xff0c;网上搜了一下有一个 vue3-clipboard 直接支持vue3&#xff0c;到github仓库看了下&#xff0c;原作者已经不维护这个项目了&#xff1a; 推荐使用 vueuse 自带的 useclipboard 功能&#xff0c;由 vue 团队维护&#xff0c;稳定性基本没问题 官…

UDP服务端和客户端通信代码开发流程

一、UDP通信 TCP&#xff1a;传输控制协议&#xff0c;面向连接的&#xff0c;稳定的&#xff0c;可靠的&#xff0c;安全的数据集流传递 稳定和可靠:丢包重传 数据有序:序号和确认序号 流量控制:稳定窗口 UDP&#xff1a;用户数据报协议 面向无连接的,不稳定的,不可靠,不安…

数据链路层协议【MAC帧和ARP协议】

全文目录 以太网帧格式MAC地址MAC地址和IP地址对比理解 MTU定义&#xff1a;细节&#xff1a;为什么它重要&#xff1a; MTU对IP协议的影响MTU对TCP和UDP的影响 ARP协议ARP数据报的格式ARP协议的作用ARP协议的工作流程 以太网帧格式 定义: 以太网是一种数据链路层和物理层标准…

【机器学习】几种常用的机器学习调参方法

在机器学习中&#xff0c;模型的性能往往受到模型的超参数、数据的质量、特征选择等因素影响。其中&#xff0c;模型的超参数调整是模型优化中最重要的环节之一。超参数&#xff08;Hyperparameters&#xff09;在机器学习算法中需要人为设定&#xff0c;它们不能直接从训练数据…

儿童产品和婴儿产品上架亚马逊美国站CPC认证测试标准

婴儿橡皮奶嘴 (ASTM F963, EN 1400, AS 2432) 婴儿奶嘴夹 (EN 12586, BS EN 12586) 婴儿学步车 (ASTM F977, EN 1273, BS EN 1273) 婴儿背带 (ASTM F2236, EN 13209, BS EN 13209) 奶瓶奶嘴 (EN 14350, BS EN 14350) 家用双层床 (ASTM F1427, EN 747, BS EN 747, AS/NZS 4…

uni-app小程序使用vant

步骤一&#xff1a;安装 Vant Weapp # 通过 npm 安装 npm i vant/weapp -S --production# 通过 yarn 安装 yarn add vant/weapp --production# 安装 0.x 版本 npm i vant-weapp -S --production步骤二&#xff1a;在根目录下创建“wxcomponents”文件夹 步骤三&#xff1a;找…

win7中安装node14和vue

下载并安装低版本node 13 到官网去找早期历史版本的 nodejs 13 msi格式即可&#xff0c;并一键安装&#xff0c;我安装在了 D:\Program Files\nodejs 目录下 https://nodejs.org/download/release/v13.14.0/ 下载高版本node 14 下载高版本的node zip包 https://nodejs.org/…

AndroidPicker的使用

项目地址&#xff1a;https://github.com/gzu-liyujiang/AndroidPicker 历史版本:https://github.com/gzu-liyujiang/AndroidPicker/blob/master/ChangeLog.md 依赖配置 // JitPack 远程仓库&#xff1a;https://jitpack.iomaven { url https://jitpack.io } 所有选择器的基…

网络安全(网络安全)小白自学

想自学网络安全&#xff08;黑客技术&#xff09;首先你得了解什么是网络安全&#xff01;什么是黑客&#xff01; 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全…

利用日期创建文件-多用于数据库的备份

功能&#xff1a;根据日期变化实现文件的创建 1&#xff09;知识点&#xff0c;date命令的用法 --date"n day ago" %Y%m%d #n天前&#xff0c;当天则可以去掉--date参数 2&#xff09;文件名的拼接 ${filename}${date} 3查看结果文件 后期学循环语句可以改一下…

git,ssh,sourcetree代码管理

安装Git并建立与GitHub的ssh连接 1、安装git&#xff0c;设置git的用户信息&#xff08;需要通过用户信息来显示你是谁&#xff09; 2、配置SSH&#xff0c; 因为本地Git仓库和GitHub仓库之间的传输是通过SSH加密传输的&#xff0c;GitHub需要识别是否是你推送&#xff0c;Git…

部署ELK

一、elasticsearch #拉取镜像 docker pull elasticsearch:7.12.1 #创建ELK docker网络 docker network create elk #启动ELK docker run -d --name es --net elk -P -e "discovery.typesingle-node" elasticsearch:7.12.1 #拷贝配置文件 docker cp es:/usr/share/el…

HTML脚本、字符实体、URL

HTML脚本&#xff1a; JavaScript 使 HTML 页面具有更强的动态和交互性。 <script> 标签用于定义客户端脚本&#xff0c;比如 JavaScript。<script> 元素既可包含脚本语句&#xff0c;也可通过 src 属性指向外部脚本文件。 JavaScript 最常用于图片操作、表单验…

网络安全好就业吗?

现目前而言&#xff0c;网络安全工程师仍是比较紧缺的。但网络安全行业前景好并≠网络安全的入学门槛低&#xff0c;也≠网络安全行业适合所有转岗的人。行业紧缺的一直是技术过硬&#xff0c;德才兼备的优秀人才。 一、网络安全适合哪些人&#xff1f; 首先&#xff0c;是对…

K8s Error: ImagePullBackOff 故障排除

Error: ImagePullBackOff 故障排除 1. 起因 起因是要在一组k8s环境下做个Prometheus的测试,当时虚拟机用完直接暂停了. 启动完master和node节点后重启了这些节点. 当检查dashboard时候发现Pod处于ImagePullBackOff状态,使用命令查看详细情况 kubectl describe pods -n kuber…

极简安装win10

0 概述 本文适合那些追求高性能的人。本文的重点不是具体步骤&#xff0c;而是使用高效系统的思路。 0.1 为什么选win10? 虽然目前win11都出来了&#xff0c;但很吃硬件&#xff0c;新机i12,i13的可以装win11。像我们这些买电脑好几年的(i7),还是win10更合适。 0.2 重装效…

R语言用jsonlite库写的一个图片爬虫

以下是一个使用R语言和jsonlite库下载图片的程序。首先&#xff0c;我们需要导入jsonlite库和options()函数&#xff0c;然后将代理服务器的主机名和端口号设置为"duoip"和"8000"。接着&#xff0c;我们将URL设置为"https://yun.baidu.com/"&…

R语言如何写一个爬虫代码模版

R语言爬虫是利用R语言中的网络爬虫包&#xff0c;如XML、RCurl、rvest等&#xff0c;批量自动将网页的内容抓取下来。在进行R语言爬虫之前&#xff0c;需要了解HTML、XML、JSON等网页语言&#xff0c;因为正是通过这些语言我们才能在网页中提取数据。 在爬虫过程中&#xff0c;…

链表指定结点的删除

删除节点就是将指定结点从链表中删除。 删除节点分为两种情况&#xff0c;一种是链表头删除&#xff0c;另一中链表中间或尾部删除。将待删节点于前一结点解除指向(中间或尾部)或直接删除该节结点并重建链表头(头节点)。 删除结点有以下情况&#xff1a; 1.链表为空&#xf…

ASTM F963-23美国玩具安全新标准发布

新标准发布 2023年10月13日&#xff0c;美国材料与试验协会&#xff08;ASTM&#xff09;发布了新版玩具安全标准ASTM F963-23。 主要更新内容 与ASTM F963-17相比&#xff0c;此次更新包括&#xff1a;单独描述了基材重金属元素的豁免情况&#xff0c;更新了邻苯二甲酸酯的管控…