C++ 知道虚函数表的存在
今天翻看陈皓大大的博客,直接找关于C++的东东,看到了虚函数表的内容,找一些能看得懂的地方记下笔记。
0 引子
类中存在虚函数,就会存在虚函数表,在vs2015的实现中,它存在于类的头部。
假设有如下类:
class Base {
public:
virtual void f() { cout << "Base::f" << endl; }
virtual void g() { cout << "Base::g" << endl; }
virtual void h() { cout << "Base::h" << endl; }
};
虚函数指针和虚函数指针示意图(图片来源于参考资料[1])

1 查看
typedef void(*Fun)(void);
Base b;
Fun pFun = NULL;
cout << "虚函数表地址:" << (int*)(&b) << endl;
cout << "虚函数表 — 第一个函数地址:" << (int*)*(int*)(&b) << endl;
pFun = (Fun)*((int*)*(int*)(&b));
pFun();
讲解代码:
强行把&b转成int *,取得虚函数表的地址,然后,再次取址就可以得到第一个虚函数的地址了,也就是Base::f(),这在上面的程序中得到了验证(把int* 强制转成了函数指针)。通过这个示例,我们就可以知道如果要调用Base::g()和Base::h(),其代码如下:
(Fun)*((int*)*(int*)(&b)+0); // Base::f()
(Fun)*((int*)*(int*)(&b)+1); // Base::g()
(Fun)*((int*)*(int*)(&b)+2); // Base::h()
2 为什么写这篇文章
(1) 了解虚函数表的存在,作为接下来学习的知识储备;
(2) 记住陈皓大大获取虚函数表的时候多次强制转换指针;
(3) 另外这里的讨论有错误之处,http://bbs.csdn.net/topics/320008423 ,自己要看下靠谱书籍纠正这些错误,我暂时相信陈皓大大的讲解。
参考:
[1] C++虚函数表解析.陈皓.http://blog.csdn.net/haoel/article/details/1948051
C++ 知道虚函数表的存在的更多相关文章
- C++ 虚函数表解析
转载:陈皓 http://blog.csdn.net/haoel 前言 C++中 的虚函数的作用主要是实现了多态的机制.关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实 ...
- C++ 多态、虚函数机制以及虚函数表
1.非virtual函数,调用规则取决于对象的显式类型.例如 A* a = new B(); a->display(); 调用的就是A类中定义的display().和对象本体是B无关系. 2. ...
- C++迟后联编和虚函数表
先看一个题目: class Base { public: virtual void Show(int x) { cout << "In Base class, int x = & ...
- C++虚函数和虚函数表
前导 在上面的博文中描述了基类中存在虚函数时,基类和派生类中虚函数表的结构. 在派生类也定义了虚函数时,函数表又是怎样的结构呢? 先看下面的示例代码: #include <iostream> ...
- C++ Daily 《5》----虚函数表的共享问题
问题: 包含一个以上虚函数的 class B, 它所定义的 对象是否共用一个虚函数表? 分析: 由于含有虚函数,因此对象内存包含了一个指向虚函数表的指针,但是这个指针指向的是同一个虚函数表吗? 实验如 ...
- C++虚函数表
大家知道虚函数是通过一张虚函数表来实现的.在这个表中,主要是一个类的虚函数的地址表,这张表解决了继承.覆盖的问题,其内容真是反应实际的函数.这样,在有虚函数的类的实例中,这个表分配在了这个实例的内存中 ...
- 对C++虚函数、虚函数表的简单理解
一.虚函数的作用 以一个通用的图形类来了解虚函数的定义,代码如下: #include "stdafx.h" #include <iostream> using name ...
- 深入理解C++虚函数表
虚函数表是C++类中存放虚函数的一张表,理解虚函数表对于理解多态很重要. 本次使用的编译器是VS2013,为了简化操作,不用去操作函数指针,我使用到了VS的CL编译选项来查看类的内存布局. CL使用方 ...
- C++虚函数与虚函数表
多态性可分为两类:静态多态和动态多态.函数重载和运算符重载实现的多态属于静态多态,动态多态性是通过虚函数实现的. 每个含有虚函数的类有一张虚函数表(vtbl),表中每一项是一个虚函数的地址, 也就是说 ...
随机推荐
- C#中浮点数依IEEE-754标准转二进制串 (MODBUS 浮点数转换)
因工作需要,把再串口通信中浮点数与字节流的数据转换函数放在这,转发的,谢谢原作者. 今天花了一天的时间搜罗资料,为了解决一个串口编程的进制转化问题.因为串口传送的浮点数据格式与IEEE-754标准(3 ...
- 设计一个泛型类orderedCollection
设计一个泛型类orderedCollection,它存储的Comparable对象的集合(在数组中),以及该集合的当前大小.提供public方法isEmpty,makeEmpty,insert,rem ...
- HTLM5第一天的内容
网页的本质就是超级文本标记语言:Hyper Text Markup Language 网页的组成:结构(HTML) 样式(CSS) 行为(JavaScript) 万维网联盟:W3C:World W ...
- SQL 存储过程 分页查询
ALTER PROCEDURE [dbo].[gzProc_TablePage] @tablename varchar(MAX),--表名 @selcolumn varchar(MAX),--查询字段 ...
- Adobe Photoshop CC (32/64位) 绿色精简版
32位版下载地址:http://pan.baidu.com/share/link?uk=33907222&shareid=3828486959 64位版下载地址:http://pan.baid ...
- IE9 打不开界面也不报错,只有打开控制台才会显示 - console
IE9下,打开界面不报错也不展示数据,打开控制台时就能加载出数据,有可能是代码中有console
- git备份sublime插件及配置
github备份sublime配置 sublime使用的时间长了,渐渐的就积累了一些有用甚至离不开的插件.但是有时候系统会出点问题,或者换电脑什么的,这时候要想在找回那个曾经的sublime就不那么容 ...
- mybatis-mysql操作存储过程
java代码: @RequestMapping(value = "/testProcedure", method = RequestMethod.GET) public @Resp ...
- java String 的+操作导致的问题
不说别的先看代码截图: 结果如下: 很好奇为什么String对象的null加上了""就等于"null"字符串了,先给点资料看看: 这个是我找的一个人博客上的截图 ...
- System.Data.SqlClient.SqlError:无法对过程'XXX' 执行 删除,因为它正用于复制。消息 3724,级别 16
遇到这么一个错误,想对[northwindcs]这个数据库搭建复制,从B服务器发布订阅到C服务器,采用备份还原进行初始化,但是在数据库还原时,报无法对过程‘XXX’执行删除,因为它正用于复制.表面上一 ...