c++虚函数与虚函数表原理
作者:考拉爱睡觉鸭~ 发布时间:2023-12-09 07:22:45
标签:c++,虚函数,虚函数表
1.什么是虚函数?
用virtual
修饰的成员函数叫虚函数
小知识: 没有虚构造函数 不写虚函数,没有默认的虚函数
普通函数不影响类的内存:
class MM
{
public:
void print()
{
cout << "普通函数"<< endl; //普通函数不影响类的内存<--->普通函数存在另一段内存中
}
protected:
};
void testVirtual()
{
//C语言不允许存在空的结构体
cout << sizeof(MM) << endl;/*(没有数据成员的)空的类或者结构体 占用1字节 用1字节标识当
前内存为结构体内存*/
}
int main()
{
testVirtual();
return 0;
}
/*输出*/
/* 1 */
2.虚函数会影响类的内存
增加一个指针的内存,32位操作系统多4个字节 ,64位操作系统多8个字节
#include <iostream>
using namespace std;
class MM
{
public:
virtual void print1()
{
cout << "虚函数1"<< endl;
}
/*virtual void print2()
{
cout << "虚函数2" << endl;
} 无论多少个虚函数,增加的字节就是一个指针的字节--->多了一个虚函数,还是4个字节*/
protected:
};
void testVirtual()
{
cout << sizeof(MM) << endl;
}
int main()
{
testVirtual();
return 0;
}
/*输出*/
/* 4 */
小知识:一旦有了数据,标识位就不需要存在了
class A
{
int num; //输出4而不是5 (4+1)
};
class B
{
//用1字节标识当前内存为结构体内存
};
void testVirtual()
{
cout << sizeof(A) << endl;
cout << sizeof(B) << endl;
}
int main()
{
testVirtual();
return 0;
}
/*输出*/
/*4
1*/
3.了解虚函数表--->通过虚函数表的指针去访问数据
就是一个指针存储所有虚函数的首地址(虚函数函数名)<--->函数指针
只有指针可以操作一段内存(4字节)
/*无论多少个虚函数,增加的字节就是一个指针的字节*/
所有的虚函数其实是 用一个函数指针去存储的 ,把 这个函数指针指向的这一段内存 称为虚函数表
#include <iostream>
using namespace std;
class MM
{
public:
virtual void print1()
{
cout << "虚函数1"<< endl;
}
virtual void print2()
{
cout << "虚函数2"<< endl;
}
protected:
};
void testVirtual()
{
//虚函数表
MM mm; //构建一个对象
int** vptr = (int** )&mm; //定义一个二级指针&对象的地址 强转类型
typedef void(*PF)(); //函数指针定义别名
PF func = (PF)vptr[0][0]; //把地址转为函数指针,访问第一个函数指针的地址
func(); //通过虚函数表的函数指针调用第一个虚函数
func = (PF)vptr[0][1];
func(); //调用第二个虚函数
}
int main()
{
testVirtual();
return 0;
}
/*输出*/
/*虚函数1
虚函数2*/
4.虚函数声明
虚函数可以在类中声明,在类外实现,不再需要virtual
修饰词,只要类名限定就可以了
class MM
{
public:
virtual void print3();
protected:
};
void MM::print3() {
cout << "虚函数3" << endl;
}
int main()
{
MM mm;
mm.print3();
return 0;
}
/*输出*/
/*虚函数3*/
来源:https://blog.csdn.net/weixin_60569662/article/details/121722479
0
投稿
猜你喜欢
- Lambda用到了JDK8自带的一个函数式接口Comparator<T>。准备一个Apple类public class Appl
- //param objArr the expanded object of Array. &
- Intersect子句一、简介Intersect返回交集,交集是指同时出现在两个集合中的元素,和数据库中的Intersect方法实现功能一样
- 前言其实Task跟线程池ThreadPool的功能类似,不过写起来更为简单,直观。代码更简洁了,使用Task来进行操作。可以跟线程一样可以轻
- java金钱处理方法实例详解在支付行业中,涉及到对金钱的处理比较多。比如分转化成元、费率计算、手续费计算等等。1.分转化成元/** &nb
- 读取xml配置bean(@ImportResource)1、应用场景旧框架SSM项目移行到SpringBoot中,xml配置文件很齐全,就可
- Java注解介绍基于注解(Annotation-based)的Java开发无疑是最新的开发趋势.[译者注: 这是05年的文章,在2014年,
- 废话不多说,直接上代码package com.ncu.list;/** * * 顺序结构线性列表 *&nbs
- 在实际项目开发中,业务逻辑层的处理速度往往很快,特别是在开发Socket通信服务的时候,网络传输很快,但是一旦加上数据库操作,性能一落千丈,
- spring Cache注解和redis区别1.不支持TTL即不能设置过期时间 expires time,SpringCache 认为这是各
- java jdbc连接和使用jdbc导入驱动//jar是已经打包好的class文件集,可以引用到其他工程中 //Build Pa
- 本篇博客我们继续的来聊SpringMVC的东西,下方我们将会聊到js、css这些静态文件的加载配置,以及服务器推送的两种实现方式。当然我们在
- springboot加载yml文件获不到值今天使用spring boot读取yml文件,这种多层嵌套的竟然无法读取到(value注解spri
- 介绍跨域CORS,全称是"跨域资源共享"(Cross-origin resource sharing)当页面发出跨域请求
- 本文实例讲述了C#实现的XML操作类。分享给大家供大家参考。具体如下:这里讲述了C#写的一个XML操作类,包括读取/插入/修改/删除。usi
- springboot jpa 延迟加载问题在springboot中,在application.properties的配置文件中新增sprin
- java的比较器有两类,分别是Comparable接口和Comparator接口。在为对象数组进行排序时,比较器的作用非常明显,首先来讲解C
- SpringBoot自带Tomcat,所以我们的项目可以单独部署,不需要依赖Window、Linux系统中的服务器,所以打包出来的Jar包是
- 1.设计原理通过JDK的Proxy方式或者CGLIB方式生成代理对象的时候,相关的 * 已经配置到代理对象中去了;通过 * 回调JDK动态代
- 流程:Springboot开发过程还有一个是mybatis的依赖测试接口@RestControllerpublic class Hello