# 深入了解C++虚指针
## 什么是虚函数表
指针大小是固定的,无论该指针指向哪种数据类型,32位机为4个字节,64位机为8个字节。
C++标准规定,凡是一个独立的(非附属)对象都必须具有非零大小,即C++空类大小不能为0。验证空类大小为1。

虚函数表:
在64位机中,如果类中存在虚函数,那么该类的大小就会多8个字节,然而这8个字节就是一个指针的大小,这个指针指向虚函数表。所以,如果对象存在虚函数,那么编译器就会生成一个指向虚函数的指针,所有的虚函数都存在于这个表中,虚函数表就可以理解为一个数组,每个单元用来存放虚函数的地址。下面来测试验证:
~~~
#include <iostream>
using namespace std;
class foo1 {
};
class foo2 {
void f();
};
class foo3 {
virtual void f();
};
class foo4 {
int a;
};
class foo5 {
int a;
void f();
};
class foo6 {
int a;
virtual void f();
};
class foo7 {
int a;
int b;
virtual void f();
};
int main() {
cout << "sizeof(foo1)=" << sizeof(foo1) << endl;
cout << "sizeof(foo2)=" << sizeof(foo2) << endl;
cout << "sizeof(foo3)=" << sizeof(foo3) << endl;
cout << "sizeof(foo4)=" << sizeof(foo4) << endl;
cout << "sizeof(foo5)=" << sizeof(foo5) << endl;
cout << "sizeof(foo6)=" << sizeof(foo6) << endl;
cout << "sizeof(foo7)=" << sizeof(foo7) << endl;
return 0;
}
~~~
输出结果
~~~
sizeof(foo1)=1
sizeof(foo2)=1
sizeof(foo3)=8
sizeof(foo4)=4
sizeof(foo5)=4
sizeof(foo6)=16
sizeof(foo7)=16
~~~
以上结果明显,普通成员函数不占空间大小,如果类中加入一个虚函数,则整个类的大小增加8个字节(一个指针大小)。foo3增加7个字节大小是要减去空类规定的大小1。foo6增加12个字节大小,是因为增加一个虚函数指针8个字节,后面成员变量大小为4,和前面字节对齐,则总大小为16,foo7验证是对的。
虚函数:
虚函数是通过一张虚函数表来实现的,简称V-Table。这个表中,主要是一个类的虚函数的地址表,这张表解决了继承、覆盖的问题,保证其真实反应实际的函数。这样,在有虚函数的类的实例中分配了指向这个表的指针的内存,所以,当用父类的指针来操作一个子类的时候,这张虚函数表就显得尤为重要了,它就像一个地图一样,指向了实际所应该调用的函数。
- 空白目录
- 算法
- 排序
- 冒泡排序
- 选择排序
- 插入排序
- 归并排序
- 快速排序
- 计数排序
- 桶排序
- 基数排序
- 希尔排序
- 堆排序
- 二分查找
- 最小堆
- 最小索引堆
- 平衡二叉树(AVL tree)
- bitmap位图
- 布隆过滤器
- hashmap
- topK
- 跳表
- LRU Cache
- kmp
- 最小堆和堆排序
- 最短路径
- C++
- 运行时类型判断RTTI
- C++反射
- 手动实现智能指针
- 序列化实现
- rpc实现
- std::forward
- 函数指针的妙用
- C/C++
- std::function
- 同步队列
- 线程池实现
- std::promise
- 深入理解虚函数
- extern "C" 关键字讲解
- 大端小端的区别
- 简历
- 简历1
- redis
- 数据结构和对象
- sds
- list
- zskiplist
- 腾讯云redis面试题总结
- redis集群部署
- LeetCode
- 目标
- go基础
- 算法快速入门
- 数据结构篇
- 二叉树
- 链表
- 栈和队列
- 二进制
- 基础算法篇
- 二分搜索
- 排序算法
- 动态规划
- 算法思维
- 递归思维
- 滑动窗口思想
- 二叉搜索树
- 回溯法
- 其他
- 剑指offer
- 笔记
- git代理加速
- Linux
- vim大法
- vscode远程不能跳转
- cmake
- 设计模式
- 单例模式
- 简单工厂模式
- 外观模式
- 适配器模式
- 工厂方法模式
- 抽象工厂模式
- 生成器模式
- 原型模式
- 中介者模式
- 观察者模式
- 访问者模式
- 命令模式
- 网络编程
- epoll reactor模式
- linux timerfd系列函数总结
- IO
- mapreduce
- 反射器
- leo通信库
- Mutex
- Condition
- thread
- raft
- 协程
- hook
- 定时器
- 别人的面试经验
- 面试题
- vector崩溃问题
- JAVA
- Linux java环境配置
- ucore
- lab1
- FreeNOS
- leveldb
- 刷题笔记
- 回文串
- 前缀树
- 字符串查找
- 查找两个字符串a,b中的最长公共子串
- 动态规划
- golang
- 顺序循环打印实现
- 数据结构
- rpc运用
- python
- 单例
- 深拷贝浅拷贝
- 链表
- python基础题
- mysql
- 事务
- Linux
- 共享内存
- 刷题记录
- 贪心算法
- 动态规划
- 面试
- 腾讯C++面试
- 微众面试JD
- 迅雷网络面试
- 学习网址
- rabbitMq
