先看一个简单的问题:

一、定义一个空的类型,对于其对象我们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指向的虚函数表的地址,可以打开内存查看。这意味着我们通过对象实例的地址得到这张虚函数表,然后就可以遍历其中函数指针,并调用相应的函数。

由剑指offer引发的思考——对象中虚函数指针的大小的更多相关文章

  1. 剑指Offer——常用SQL语句、存储过程和函数

    剑指Offer--常用SQL语句.存储过程和函数 常用SQL语句 1.在MySQL数据库建立多对多的数据表关系 2.授权.取消授权 grant.revoke grant select, insert, ...

  2. 剑指Offer - 九度1373 - 整数中1出现的次数(从1到n整数中1出现的次数)

    剑指Offer - 九度1373 - 整数中1出现的次数(从1到n整数中1出现的次数)2014-02-05 23:03 题目描述: 亲们!!我们的外国友人YZ这几天总是睡不好,初中奥数里有一个题目一直 ...

  3. 剑指Offer - 九度1348 - 数组中的逆序对

    剑指Offer - 九度1348 - 数组中的逆序对2014-01-30 23:19 题目描述: 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个 ...

  4. 剑指Offer - 九度1517 - 链表中倒数第k个结点

    剑指Offer - 九度1517 - 链表中倒数第k个结点2013-11-30 02:57 题目描述: 输入一个链表,输出该链表中倒数第k个结点.(hint: 请务必使用链表.) 输入: 输入可能包含 ...

  5. 剑指Offer - 九度1370 - 数组中出现次数超过一半的数字

    剑指Offer - 九度1370 - 数组中出现次数超过一半的数字2013-11-23 03:55 题目描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组 ...

  6. 剑指Offer - 九度1351 - 数组中只出现一次的数字

    剑指Offer - 九度1351 - 数组中只出现一次的数字2013-11-23 01:23 题目描述: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. ...

  7. 剑指offer:二维数组中的查找

    目录 题目 解题思路 具体代码 题目 题目链接 剑指offer:二维数组中的查找 题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺 ...

  8. 剑指 Offer 04. 二维数组中的查找 (思维)

    剑指 Offer 04. 二维数组中的查找 题目链接 本题的解法是从矩阵的右上角开始寻找目标值. 根据矩阵的元素分布特性, 当目标值大于当前位置的值时将row行号++,因为此时目标值一定位于当前行的下 ...

  9. 【剑指Offer】孩子们的游戏(圆圈中最后剩下的数) 解题报告(Python)

    [剑指Offer]孩子们的游戏(圆圈中最后剩下的数) 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-in ...

随机推荐

  1. 一统江湖的大前端(10)——inversify.js控制反转

    <大史住在大前端>前端技术博文集可在下列地址访问: [github总基地][博客园][华为云社区][掘金] 字节跳动幸福里大前端团队邀请各路高手前来玩耍,团队和谐有爱,技术硬核,字节范儿正 ...

  2. [CCPC2019网络赛] 1008-Fishing Master(思维)

    >传送门< 题意:现在需要捕$n$条鱼并且将它们煮熟来吃.每条鱼要煮相应的时间才能吃(可以多煮一会),锅里每次只能煮一条鱼,捕一条鱼的时间是相同的,但是在捕鱼的时间内不能做其他事(比如换一 ...

  3. 【uva 11572】Unique Snowflakes(算法效率--滑动窗口,3种实现方法)

    题意:求长度为N的序列中,最长的一个无重复元素的连续子序列. 解法:[L,R]每次R++或L++延伸就可以得到答案. 实现:(1)next[],last[]--O(n): 1 #include< ...

  4. 2020 ICPC Asia Taipei-Hsinchu Regional Problem H Optimization for UltraNet (二分,最小生成树,dsu计数)

    题意:给你一张图,要你去边,使其成为一个边数为\(n-1\)的树,同时要求树的最小边权最大,如果最小边权最大的情况有多种,那么要求总边权最小.求生成树后的所有简单路径上的最小边权和. 题解:刚开始想写 ...

  5. Codeforces Round #307 (Div. 2) B. ZgukistringZ

    Professor GukiZ doesn't accept string as they are. He likes to swap some letters in string to obtain ...

  6. XV6学习(14)Lab fs: File system

    代码在github上. 这次实验是要对文件系统修改,使其支持更大的文件以及符号链接,实验本身并不是很复杂.但文件系统可以说是XV6中最复杂的部分,整个文件系统包括了七层:文件描述符,路径名,目录,in ...

  7. 洛谷 P4143 采集矿石 后缀数组

    题目背景 ZRQ 成功从坍塌的洞穴中逃了出来.终于,他看到了要研究的矿石.他想挑一些带回去完成任务. 题目来源:Zhang_RQ哦对了 \(ZRQ\) 就他,嗯 题目描述 ZRQ 发现这里有 \(N\ ...

  8. Python:装饰器是如何调用的

    应用举例:(1)装饰器 # 装饰器的调用: # 一旦用上装饰器会: # 第一步:调outer函数 # 第二步:被装饰的函数play_game会被当作参数fn给outer # 第三步:最后调用play_ ...

  9. springboot demo(一)快速开始

    快速入门 maven构建项目 1.访问http://start.spring.io/ 2.选择构建工具Maven Project.Spring Boot版本2.26以及一些工程基本信息,点击" ...

  10. Doris开发手记1:解决蛋疼的MySQL 8.0连接问题

    笔者作为Apache Doris的开发者,平时感觉相关Doris的文章写的很少.主要是很多时候不知道应该去记录一些怎么样的问题,感觉写的不好就会很慌张.新的一年,希望记录自己在Doris开发过程之中所 ...