先看一个简单的问题:

一、定义一个空的类型,对于其对象我们sizeof其大小,是1字节。因为我们定义一个类型,编译器必须为其分配空间,具体分配多少是编译器决定,vs是1字节,分配在栈区。

那,这一个字节会被初始化吗?

举个例子:

#include<iostream>
class parent{ };
int main() {
parent my_par;
int a = 0;
std::cout << sizeof(my_par) << " "<< &my_par<<" "<<&a;
while (1);
return 0;
}

其输出:

我们查看内存,看得到都初始化为:CC CC CC CC

多调试几次,每次地址都不一样,但是内存值都是CC。为什么都是CC?

因为0xCC对应的是INT3断点,简单地说就是将要断下的指令地址处的第一个字节设置为0xCC,软件执行到0xCC(对应汇编指令INT3)时,会触发异常代码为EXCEPTION_BREAKPOINT的异常。这样我们的调试程序就能够接收到这个异常,然后进行相应的处理。具体.......所以,我们写的是异常代码,实际工作中空类型又有什么意义呢?具体会设计编译器逆向工程,有机会可以看看。

回到我们标题:

二、虚函数的问题

  1. 当类中声明虚函数时,编译器会在类中生成一个虚函数表,若子类自己有虚函数也会生成一个虚函数表
  2. 虚函数表是一个存储 类的virtual成员函数指针的数据结构;
  3. 当存在虚函数时,每个对象都有一个指向虚函数表的指针(类本身没有指针,有一个编译器维护的虚函数表。对象有虚函数指针,我们sizeof是测的是对象所占内存);
  4. 若一个对象继承于两个都有虚函数的父类,他要维护两个虚函数指针;
  5. 虚函数指针存在于对象实例中最前面的位置;
#include <iostream>
using namespace std; class Base1{
virtual void fun1(){}
virtual void fun11(){}
public:
virtual ~Base1();
}; class Base2{
virtual void fun2(){}
}; class DerivedFromOne: public Base2
{
virtual void fun2(){}
virtual void fun22(){}
}; class DerivedFromTwo: public Base1, public Base2 //多继承
{
virtual void fun3(){}
}; void main()
{
Base2 my_base;
cout << "sizeof Base1 " << sizeof(Base1) << "输出vptb"<<(int*)*(int*)(&my_base)<< endl;//太复杂了,以后再说。
cout << "sizeof Base2" << sizeof(Base2) << endl;
cout << "sizeof FromOne " << sizeof(DerivedFromOne) << endl;
cout << "sizeof FromTwo " << sizeof(DerivedFromTwo) << endl;
system("pause")
}

输出:

可以看出:

1、每个单继承,对象都有一个vptr指针;多继承,对象就会有多个虚函数指针指向父类的虚函数表。虚函数表不占栈内存,由编译器维护,在代码区?我们测的是对象的内存。

2、Base2的对象的地址,就是vptr指向的虚函数表的地址,可以打开内存查看。这意味着我们通过对象实例的地址得到这张虚函数表,然后就可以遍历其中函数指针,并调用相应的函数。

最新文章

  1. elasticsearch常用的概念整理
  2. webpack中alias别名配置
  3. Linux的学习之路
  4. 读Lua游戏开发实践指南
  5. idea配置maven并添加镜像配置
  6. nodejs生成UID(唯一标识符)——node-uuid模块
  7. Hdu OJ 5115 Dire Wolf (2014ACM/ICPC亚洲区北京站) (动态规划-区间dp)
  8. redis的简单安装配置
  9. View (三) 视图绘制流程完全解析
  10. vim MiniBufExplorer 插件
  11. Flashback删除(闪回删除)
  12. Sql语句之select 5种查询
  13. python 读取图片的尺寸、分辨率
  14. IDEA破解 Intellij IDEA license server 激活(可用)
  15. Unity3d中如何查找一个脚本被挂在那些预设上面?
  16. 在Ubuntu14.04上配置jdk环境
  17. ansible常用命令大全
  18. Scala面向接口
  19. [转]sqlmap使用教程
  20. cad2016卸载/安装失败/如何彻底卸载清除干净cad2016注册表和文件的方法

热门文章

  1. httprunner(2)下载安装
  2. xxl-job之实现流程任务编排思路
  3. 【poj 2891】Strange Way to Express Integers(数论--拓展欧几里德 求解同余方程组 模版题)
  4. KMP——POJ-3461 Oulipo &amp;&amp; POJ-2752 Seek the Name, Seek the Fame &amp;&amp; POJ-2406 Power Strings &amp;&amp; POJ—1961 Period
  5. poj 3468A Simple Problem with Integers
  6. 2019牛客暑期多校训练营(第六场)J Upgrading Technology
  7. Bone Collector II HDU - 2639 01背包第k最大值
  8. 牛客编程巅峰赛S1第5场 - 青铜&amp;白银 B.完全平方数的尾巴 (暴力)
  9. (数据科学学习手札106)Python+Dash快速web应用开发——回调交互篇(下)
  10. python自动化运维之CMDB篇-大米哥