如果一个类有虚函数,那么这个类的虚函数会被放在一个虚函数表里面, 使用这个类声明的对象中,会有一个指向虚函数表的指针,当使用指向 这个对象的指针或者这个对象的引用调用一个虚函数的时候,就会从虚函数表中去 查找该函数,然后对其进行调用。

如果有如下的类:

class A {
public :
int m_a;
A() {}
~A() {} virtual void test() { cout << "A info : " << __LINE__ << " , " << __func__ << endl;}
}; class B : public A{
public :
int m_b;
B() {}
~B() {} virtual void test() { cout << "B info : " << __LINE__ << " , " << __func__ << endl;}
};

那么我们显示出一个 B 类对象的内存状态, 这个类声明的对象的内存布局会是下面这样:

#ifdef __x86_64__
cout << "__x86_64__" << endl;
#else
cout << "not 64" << endl;
#endif cout << "sizeof(B) = " << sizeof(B) << endl;
cout << "sizeof(int) = " << sizeof(int) << endl; B b;
b.m_a = 0x01010101;
b.m_b = 0x02020202; show_mem(&b, sizeof(b));

执行结果:

__x86_64__
sizeof(B) =
sizeof(int) =
addrress : f8 cc fa ff 7f
memory layout : 0f

我们看到,拥有两个 int 成员变量的 b 对象,它占用的内存大小却不是 两个 sizeof(int) 的和 8,而是16。很明显,另外8个字节就是存放虚函数表地址 的了,因为目前使用的是64位系统,指针占用的空间是64 bit。

那么,我们现在知道了一个对象的内存布局后,就可以采取 "非法" 手段 调用一个虚函数了。比如下面这段代码:

#ifdef __x86_64__
typedef unsigned long int POINT_SIZE;
#else
typedef int POINT_SIZE;
#endif typedef void(*Fun)(); //获取对象的地址
POINT_SIZE *po = (POINT_SIZE *)&b; //获取这个对象前 8 个字节的值,这个值是虚函数表的地址
POINT_SIZE tbl = po[]; //把这个值转换为地址类型,也就是虚函数表的地址
POINT_SIZE *ptbl = (POINT_SIZE *)tbl; int pos = ;
//虚函数表的第一表项就是第一个虚函数的函数地址,
//这里将其转换为函数类型
Fun pfun = (Fun)(ptbl[pos]); //调用这个函数
pfun();

调用的结果是:

B info :  , test

说明调用了 B 类的虚函数,内存布局如下:

这样,我们使用非常规手段就可以调用一个类的虚函数了。


同步发表:http://www.fengbohello.top/book/b/1275

《深度探索C++对象模型》调用虚函数的更多相关文章

  1. [读书系列] 深度探索C++对象模型 初读

    2012年底-2014年初这段时间主要用C++做手游开发,时隔3年,重新拿起<深度探索C++对象模型>这本书,感觉生疏了很多,如果按前阵子的生疏度来说,现在不借助Visual Studio ...

  2. 深度探索C++对象模型

    深度探索C++对象模型 什么是C++对象模型: 语言中直接支持面向对象程序设计的部分. 对于各个支持的底层实现机制. 抽象性与实际性之间找出平衡点, 需要知识, 经验以及许多思考. 导读 这本书是C+ ...

  3. c++学习书籍推荐《深度探索C++对象模型》下载

    百度云及其他网盘下载地址:点我 百度云及其他网盘下载地址:点我 编辑推荐 如果你是一位C++程序员,渴望对于底层知识获得一个完整的了解,那么这本<深度探索C++对象模型>正适合你 作者简介 ...

  4. 《深度探索C++对象模型》读书笔记(一)

    前言 今年中下旬就要找工作了,我计划从现在就开始准备一些面试中会问到的基础知识,包括C++.操作系统.计算机网络.算法和数据结构等.C++就先从这本<深度探索C++对象模型>开始.不同于& ...

  5. 读书笔记《深度探索c++对象模型》 概述

    <深度探索c++对象模型>这本书是我工作一段时间后想更深入了解C++的底层实现知识,如内存布局.模型.内存大小.继承.虚函数表等而阅读的:此外在很多面试或者工作中,对底层的知识的足够了解也 ...

  6. 拾遗与填坑《深度探索C++对象模型》3.3节

    <深度探索C++对象模型>是一本好书,该书作者也是<C++ Primer>的作者,一位绝对的C++大师.诚然该书中也有多多少少的错误一直为人所诟病,但这仍然不妨碍称其为一本好书 ...

  7. 拾遗与填坑《深度探索C++对象模型》3.2节

    <深度探索C++对象模型>是一本好书,该书作者也是<C++ Primer>的作者,一位绝对的C++大师.诚然该书中也有多多少少的错误一直为人所诟病,但这仍然不妨碍称其为一本好书 ...

  8. 【C++】深度探索C++对象模型读书笔记--Data语意学(The Semantics of data)

    1. 一个空类的大小是1 byte.这是为了让这一类的两个对象得以在内存中配置独一无二的地址. 2. Nonstatic data member 放置的是“个别的class object”感兴趣的数据 ...

  9. C++中构造函数能调用虚函数吗?(答案是语法可以,输出错误),但Java里居然可以

    环境:XPSP3 VS2005 今天黑总给应聘者出了一个在C++的构造函数中调用虚函数的问题,具体的题目要比标题复杂,大体情况可以看如下的代码: class Base { public: Base() ...

  10. EC笔记,第二部分:9.不在构造、析构函数中调用虚函数

    9.不在构造.析构函数中调用虚函数 1.在构造函数和析构函数中调用虚函数会产生什么结果呢? #; } 上述程序会产生什么样的输出呢? 你一定会以为会输出: cls2 make cls2 delete ...

随机推荐

  1. detailFormatter bootstrapTable

    detailView : true,//会导致表格最开头多出一列 detailFormatter :function(index, row, element){ var image = '<di ...

  2. tp5参数绑定

    关闭路由后的普通模式任然可以通过操作方法的参数绑定.控制器和空操作等特性实现url地址的简化 参数绑定(默认是按名称成对解析,): namespace app\index\Controller; cl ...

  3. 如何让自己的Dev C++用上C++11,c++14标准

      首先确保Dev C++版本是最新的5.11版 其实用C++11和C++14标准的语法去运行还是会出现结果的,最多warning一下 但完美主义者是不允许这样的 我们可以点击菜单栏的“工具”-> ...

  4. Shell学习之条件测试(四)

    Shell学习之条件测试 目录 逻辑测试 文件测试 数值比较 字符串比较 逻辑测试 格式: [ 表达式 ] 操作符 [ 表达式2 ] …… 命令1 操作符 命令2 …… 常用的操作符 ( 注意:-a和 ...

  5. 洛谷.3369.[模板]普通平衡树(Splay)

    题目链接 第一次写(2017.11.7): #include<cstdio> #include<cctype> using namespace std; const int N ...

  6. git 命令的使用

    hello git 穿越时空 修改一条数据 git status 查看是否修改 git diff file1 如何修改的 git add file1 git commit -m "提交的信息 ...

  7. BZOJ3536 : [Usaco2014 Open]Cow Optics

    枚举最后光线射到终点的方向,求出从起点出发以及从终点出发的光路,扫描线+树状数组统计交点个数即可. 注意当光路成环时,对应的两个方向应该只算一次. 时间复杂度$O(n\log n)$. #includ ...

  8. 如何查看linux版本信息

    查看系统信息 [root@root]# hostnamectl Static hostname: root Icon name: computer-desktop Chassis: desktop M ...

  9. mysql的基本查询(等于,不等于,between...and...,)

    单个字段多个字段查询 查询员工姓名 *注:在SQL语句中不区分大小写:SQL语句以“:”分号结束 select ename from emp; 注:select询句后面跟的是字段名称,select是关 ...

  10. 小甲鱼Python第十四课后习题

    字符串格式化符号含义    符   号    说     明      %c    格式化字符及其ASCII码[>>> '%c' %97        'a']      %s    ...