深入理解C++虚函数表
虚函数表是C++类中存放虚函数的一张表,理解虚函数表对于理解多态很重要。
本次使用的编译器是VS2013,为了简化操作,不用去操作函数指针,我使用到了VS的CL编译选项来查看类的内存布局。
CL使用方法:
(1)在开始菜单中的vs目录下打开"Visual Studio Tools"目录,找到"VS2013 开发人员命令提示",打开它;
(2)将你要编译的文件放到该命令行对应的文件夹中。
(3)输入cl "文件名" /d1reportSingleClassLayout"类名"
(具体的使用方法可以参考以下博客:http://www.cnblogs.com/dsky/archive/2012/02/07/2340984.html)
例子:
#include <iostream>
using namespace std; class C {
public:
int a;
int b;
}; int main() {
return ;
}
输出结果:

(1)单个类的虚函数表
class C {
public:
virtual void foo() {}
int m;
};

结果分析:可以看见虚表处于类的最开始处,这是为了提高效率和正确查找虚函数。
(2)单继承
class Base {
public:
virtual void v1() {}
int b;
};
class Derived : public Base {
public:
virtual void v2() {}
int d;
};

结果分析:在类Derived的最前面是类Base,与我们所预期的一样。虚表并不是Base和Derived都有,而是只有Base有,Derived中的虚函数放在了Base里的虚表中。
(3)单继承 + 覆盖
class Base {
public:
virtual void v1() {}
int b;
};
class Derived : public Base {
public:
virtual void v1() {}
virtual void v2() {}
int d;
};

结果分析:我们在Derived中覆盖了Base的v1,从结果可以看出虚表中原来的Base::v1变为了Derived::v1
(4)多继承
class Base1 {
public:
virtual void v1() {}
int b1;
};
class Base2 {
public:
virtual void v2() {}
int b2;
};
class Derived : public Base1, public Base2 {
public:
virtual void v3() {}
int d;
};

结果分析:两个基类各自有自己的虚表,而Derived的虚函数放在了第一张虚表中。
(5)虚继承
class VBase {
public:
virtual void vb1(){}
int vb;
};
class Base1 : virtual public VBase {
public:
virtual void v1() {}
int b1;
};
class Base2 : virtual public VBase {
public:
virtual void v2() {}
int b2;
};
class Derived : public Base1, public Base2 {
public:
virtual void v3() {}
int d;
};

结果分析:虚继承后,基类中多了一张虚类表(vbtable),该虚类表记录的是到虚类的偏移量,比如4+24 = 28。而虚函数表的情况一如我们之前讨论。再细看,我们发现虚基类并不作为继承类的一部分,而是由虚类表来找到。
深入理解C++虚函数表的更多相关文章
- 从逆向的角度去理解C++虚函数表
很久没有写过文章了,自己一直是做C/C++开发的,我一直认为,作为一个C/C++程序员,如果能够好好学一下汇编和逆向分析,那么对于我们去理解C/C++将会有很大的帮助,因为程序中所有的奥秘都藏在汇编中 ...
- 我理解的C++虚函数表
今天拜读了陈皓的C++ 虚函数表解析的文章,感觉对C++的继承和多态又有了点认识,这里写下自己的理解.如果哪里不对的,欢迎指正.如果对于C++虚函数表还没了解的话,请先拜读下陈皓的C++ 虚函数表解析 ...
- 对C++虚函数、虚函数表的简单理解
一.虚函数的作用 以一个通用的图形类来了解虚函数的定义,代码如下: #include "stdafx.h" #include <iostream> using name ...
- 深入理解类成员函数的调用规则(理解成员函数的内存为什么不会反映在sizeof运算符上、类的静态绑定与动态绑定、虚函数表)
本文转载自:http://blog.51cto.com/9291927/2148695 总结: 一.成员函数的内存为什么不会反映在sizeof运算符上? 成员函数可以被看作是类 ...
- C++虚函数表理解
一,思维模式图 二,代码验证 class A { public: A(int x) { fProtected = x; } float GetFProtected() { return fProtec ...
- C++ 虚函数表与内存模型
1.虚函数 虚函数是c++实现多态的有力武器,声明虚函数只需在函数前加上virtual关键字,虚函数的定义不用加virtual关键字. 2.虚函数要点 (1) 静态成员函数不能声明为虚函数 可以这么理 ...
- C++虚函数及虚函数表解析
一.背景知识(一些基本概念) 虚函数(Virtual Function):在基类中声明为 virtual 并在一个或多个派生类中被重新定义的成员函数.纯虚函数(Pure Virtual Functio ...
- 关于C++中虚函数表存放位置的思考
其实这是我前一段时间思考过的一个问题,是在看<深入探索C++对象模型>这本书的时候我产生的一个疑问,最近在网上又看到类似的帖子,贴出来看看: 我看到了很多有意思的答案,都回答的比较好,下面 ...
- c++ 继承类强制转换时的虚函数表工作原理
本文通过简单例子说明子类之间发生强制转换时虚函数如何调用,旨在对c++继承中的虚函数表的作用机制有更深入的理解. #include<iostream> using namespace st ...
随机推荐
- Java基础语法的学习
首先就是关于枚举类型的思考与实践,这个是在jdk5.0及以后的版本才有的,然后对枚举类型进行动手操作. 源代码: package test; public class EnumTest { publi ...
- java发送短信--httpclient方式
最近头让我写个发送短信的java程序检测BI系统,检查数据库是否有异常发送,有则发送短信到头的手机里.这里我直说httpclient方式的get请求方式,并且已经有方式的短信的接口了,所以只要再加上参 ...
- bootstrap datetimepicker 中只显示年或者只显示月份
1.只显示datetimepicker 日历中只显示年份 $("#day-access-calendar").datepicker({ startView: 2, maxView ...
- iris数据集
iris以鸢尾花的特征作为数据来源,数据集包含150个数据集,分为3类,每类50个数据,每个数据包含4个属性,是在数据挖掘.数据分类中非常常用的测试集.训练集. 链接地址
- myeclipse下拷贝的项目,tomcat下部署名称和导出为war包的名称默认值修改
拷贝一个项目,作为一个新的项目,给它换了名字,这时候默认的部署名称等都是原来项目的,这时候要在属性里面修改一下.
- ccc 使用let
//如果不是恩雅,也不在移动过程中,那么移动 if (!self.hasMoved && !isHold) { var touchLoc = touch.getLocation(); ...
- ccc let
let,其实就是块级作用域申明变量的var.之前JS的var关键字是非块级作用域的,而是函数级的. 例如arr=[0,1,2],我们经常写循环 for(var i=0,len=arr.length; ...
- IO中同步、异步与阻塞、非阻塞的区别
一.同步与异步同步/异步, 它们是消息的通知机制 1. 概念解释A. 同步所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回. 按照这个定义,其实绝大多数函数都是同步调用(例如si ...
- css切背景图片(background-position)
给元素添加背景图片的方式有很多,个人总结的有: 用img插入图片: css3的方式手动绘图: 单独用background-image单独插入图片: 其中用background-image有两种方法,一 ...
- 【bzoj2809】[Apio2012]dispatching 左偏树
2016-05-31 15:56:57 题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2809 直观的思想是当领导力确定时,尽量选择薪水少的- ...