所有结果均为32位系统,指针为4个字节

简单继承

class A {
public:
int a;
}; class B : public A {
public:
int b;
};

对象B的内存布局:

b --> +-----------+
| a |
+-----------+
| b |
+-----------+

简单继承虚函数

class A {
public:
int a;
virtual void v();
}; class B : public A {
public:
int b;
};

对象B内存布局

/*
+-----------------------+
| 0 (top_offset) |
+-----------------------+
b --> +----------+ | ptr to typeinfo for B |
| vtable |-------> +-----------------------+
+----------+ | A::v() |
| a | +-----------------------+
+----------+
| b |
+----------+

简单多重继承

class A {
public:
int a;
virtual void v();
}; class B {
public:
int b;
virtual void w();
}; class C : public A, public B {
public:
int c;
};

对象C的内存布局

/*

                           +-----------------------+
| 0 (top_offset) |
+-----------------------+
c --> +----------+ | ptr to typeinfo for C |
| vtable |-------> +-----------------------+
+----------+ | A::v() |
| a | +-----------------------+
+----------+ | -8 (top_offset) |
| vtable |---+ +-----------------------+
+----------+ | | ptr to typeinfo for C |
| b | +---> +-----------------------+
+----------+ | B::w() |
| c | +-----------------------+
+----------+

简单多重继承(虚函数)


class A {
public:
int a;
virtual void v();
}; class B {
public:
int b;
virtual void w();
}; class C : public A, public B {
public:
int c;
void w();
};

对象C的内存布局:

/*

                           +-----------------------+
| 0 (top_offset) |
+-----------------------+
c --> +----------+ | ptr to typeinfo for C |
| vtable |-------> +-----------------------+
+----------+ | A::v() |
| a | +-----------------------+
+----------+ | C::w() |
| vtable |---+ +-----------------------+
+----------+ | | -8 (top_offset) |
| b | | +-----------------------+
+----------+ | | ptr to typeinfo for C |
| c | +---> +-----------------------+
+----------+ | thunk to C::w() |
+-----------------------+

菱形继承

class A {
public:
int a;
virtual void v();
}; class B : public A {
public:
int b;
virtual void w();
}; class C : public A {
public:
int c;
virtual void x();
}; class D : public B, public C {
public:
int d;
virtual void y();
};

对象D的内存布局:

/*

                           +-----------------------+
| 0 (top_offset) |
+-----------------------+
d --> +----------+ | ptr to typeinfo for D |
| vtable |-------> +-----------------------+
+----------+ | A::v() |
| a | +-----------------------+
+----------+ | B::w() |
| b | +-----------------------+
+----------+ | D::y() |
| vtable |---+ +-----------------------+
+----------+ | | -12 (top_offset) |
| a | | +-----------------------+
+----------+ | | ptr to typeinfo for D |
| c | +---> +-----------------------+
+----------+ | A::v() |
| d | +-----------------------+
+----------+ | C::x() |
+-----------------------+

菱形继承(虚继承)

class A {
public:
int a;
virtual void v();
}; class B : public virtual A {
public:
int b;
virtual void w();
}; class C : public virtual A {
public:
int c;
virtual void x();
}; class D : public B, public C {
public:
int d;
virtual void y();
};

对象D的内存布局:

/*

                                   +-----------------------+
| 20 (vbase_offset) |
+-----------------------+
| 0 (top_offset) |
+-----------------------+
| ptr to typeinfo for D |
+----------> +-----------------------+
d --> +----------+ | | B::w() |
| vtable |----+ +-----------------------+
+----------+ | D::y() |
| b | +-----------------------+
+----------+ | 12 (vbase_offset) |
| vtable |---------+ +-----------------------+
+----------+ | | -8 (top_offset) |
| c | | +-----------------------+
+----------+ | | ptr to typeinfo for D |
| d | +-----> +-----------------------+
+----------+ | C::x() |
| vtable |----+ +-----------------------+
+----------+ | | 0 (vbase_offset) |
| a | | +-----------------------+
+----------+ | | -20 (top_offset) |
| +-----------------------+
| | ptr to typeinfo for D |
+----------> +-----------------------+
| A::v() |
+-----------------------+
  • 这里需要注意,因为A中有虚函数,所以虚基类A前面必须带有虚表指针。

如果A中没有虚函数

class A {
public:
int a;
void v();
}; class B : public virtual A {
public:
int b;
virtual void w();
}; class C : public virtual A {
public:
int c;
virtual void x();
}; class D : public B, public C {
public:
int d;
virtual void y();
};

对象D的内存布局:

/*

                                   +-----------------------+
| 20 (vbase_offset) |
+-----------------------+
| 0 (top_offset) |
+-----------------------+
| ptr to typeinfo for D |
+----------> +-----------------------+
d --> +----------+ | | B::w() |
| vtable |----+ +-----------------------+
+----------+ | D::y() |
| b | +-----------------------+
+----------+ | 12 (vbase_offset) |
| vtable |---------+ +-----------------------+
+----------+ | | -8 (top_offset) |
| c | | +-----------------------+
+----------+ | | ptr to typeinfo for D |
| d | +-----> +-----------------------+
+----------+ | C::x() |
| a | +-----------------------+
+----------+

C++虚表详解的更多相关文章

  1. C++ 虚函数详解

    C++ 虚函数详解 这篇文章主要是转载的http://blog.csdn.net/haoel/article/details/1948051这篇文章,其中又加入了自己的理解和难点以及疑问的解决过程,对 ...

  2. 《招一个靠谱的移动开发》iOS面试题及详解(上篇)

    以下问题主要用于技术的总结与回顾 主要问题总结 单例的写法.在单利中创建数组应该注意些什么. NSString 的时候用copy和strong的区别. 多线程.特别是NSOperation 和 GCD ...

  3. SQLServer 常见SQL笔试题之语句操作题详解

    SqlServer 常见SQL笔试题之语句操作题详解 by:授客 QQ:1033553122 测试数据库 CREATE DATABASE handWriting ON PRIMARY ( name = ...

  4. C++的virtual详解

    类的多态特性是支持面向对象的语言最主要的特性,有过非面向对象语言开发经历的人,通常对这一章节的内容会觉得不习惯,因为很多人错误的认为,支持类的封装的语言就是支持面向对象的,其实不然,Visual BA ...

  5. 【转载】图说C++对象模型:对象内存布局详解

    原文: 图说C++对象模型:对象内存布局详解 正文 回到顶部 0.前言 文章较长,而且内容相对来说比较枯燥,希望对C++对象的内存布局.虚表指针.虚基类指针等有深入了解的朋友可以慢慢看.本文的结论都在 ...

  6. c++多态性详解(转)

    什么是多态? 多态一词最初来源于希腊语,意思是具有多种形式或形态的情形,当然这只是字面意思,它在C++语言中多态有着更广泛的含义. 这要先从对象的类型说起!对象的类型有两种: 实例:Derived1类 ...

  7. (转)oracle视图详解

    Oracle视图详解   一. 视图的定义 视图(view),也称虚表, 不占用物理空间,这个也是相对概念,因为视图本身的定义语句还是要存储在数据字典里的.视图只有逻辑定义.每次使用的时候,只是重新执 ...

  8. Linq之旅:Linq入门详解(Linq to Objects)

    示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细介绍 .NET 3.5 中引入的重要功能:Language Integrated Query(LINQ,语言集 ...

  9. 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)

    一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...

随机推荐

  1. autoMapper dotnetcore webapi 自动添加映射 abp

    在ef的xxxxApplicationModule的Initialize方法中,已经添加了自动映射的配置,如下图: 写的很明白了,我们只需要写一个类继承Profile就可以了.如下图所示: 这样就可以 ...

  2. MAC系统上不能调试华为手机

    调试问题: 使用MACOS会发现在android 开发环境完整的情况下,接入MOTO,SAMSUNG,HTC,ZTE等手机都可以自动识别,并可以在DDMS中查看LOGCAT,唯独华为的手机不可识别.U ...

  3. js判断手机系统(Android或IOS),跳转相应下载地址

    <script type="text/javascript"> $(document).ready(function(e) { var u = navigator.us ...

  4. 小程序快捷键(mac中)

    快捷键 格式调整  - Ctrl+S:保存文件  - Ctrl+[, Ctrl+]:代码行缩进  - Ctrl+Shift+[, Ctrl+Shift+]:折叠打开代码块  - Ctrl+C Ctrl ...

  5. 我为什么要选择RabbitMQ ,RabbitMQ简介,各种MQ选型对比(转载)

    转载自:https://www.sojson.com/blog/48.html 前言: MQ 是什么?队列是什么,MQ 我们可以理解为消息队列,队列我们可以理解为管道.以管道的方式做消息传递. 场景: ...

  6. R-CNN,SPP-NET, Fast-R-CNN,Faster-R-CNN, YOLO, SSD系列深度学习检测方法梳理

    1. R-CNN:Rich feature hierarchies for accurate object detection and semantic segmentation 技术路线:selec ...

  7. 剑指offer编程题Java实现——面试题10二进制中1的个数

    题目: 请实现一个函数,输入一个整数,输出该整数二进制表示中1的个数.例如,把9表示成二进制是1001,有2位是1,该函数输出2解法:把整数减一和原来的数做与运算,会把该整数二进制表示中的最低位的1变 ...

  8. Android RxJava zip 操作符

    不说话,直接举例 // zip 2 observables Observable.zip(Observable.just(0), Observable.just(0), BiFunction { t1 ...

  9. Java设计模式----中介者模式

    说到中介大家都不会陌生,买房子租房子有中介,出国留学有中介,买卖二手车还是有中介.那么中介到底是个什么角色呢?实际上,中介就是让买卖双方不必面对面直接交流,由他/她来完成买卖双方的交易,达到解耦买卖人 ...

  10. Javascript高级编程学习笔记(10)—— 作用域、作用域链

    昨天介绍了,JS中函数的作用域 什么词法环境之类的,可能很多小伙伴不太明白. 在今天的内容开始之前,先做个简短的声明: 词法环境这一概念是在ES5中提出的,因为词法环境主要用于保存let.const声 ...