vptr, vtable, virtual base class table

#include <iostream>
using namespace std;

class X {
	int x, y, z;
};
class Y: public virtual X {

};
class Z: public virtual X {
	virtual void f() {
	}
};
class A: public Y, public Z {
};

int main() {
	A *p;
	cout << "pointer:" << sizeof(p) << endl;
	cout << "int:" << sizeof(int) << endl;
	cout << "X:" << sizeof(X) << endl;
	cout << "Y:" << sizeof(Y) << endl;
	cout << "Z:" << sizeof(Z) << endl;
	cout << "A:" << sizeof(A) << endl;

}

  上述代码在64位的linux上的输出如下:(g++)

在32位的windows上的输出是:(VS2013)

linux下的解析如下

X的输出很好理解3*4=12。没问题。

Y虚继承了X,则Y将会有一个vptr,其中指针占8个字节。此外因为Y是空类,因此编译器会自动地添加一个字节。再加上边界对齐的3个字节。因此8+3*4+1+3=24。

Z同Y。

A多重继承Y,Z。则有两个vptr。此外A是一个空类,因此编译器会自动地添加一个字节。再加上边界对齐的3个字节。因此8+8+3*4+1+3=32。

windows下的解析如下:

关键是Y,Z和A

Y类似于linux的Y。但是VS并没有给空类生成一个字节的。因此3*4+4=16。

Z,VS编译器中,是将virtual base class table和virtual function table区分开的,因为既有虚基类,又有虚函数,因此需要虚函数表指针和虚基类表指针。因此3*4+4+4=20。

A多重继承,3*4+4+(4+4)=24。

时间: 2024-11-05 17:28:15

vptr, vtable, virtual base class table的相关文章

Empty virtual base class的内存分配

class X{}; class Y:public virtual X{}; class Z:public virtual X{}; class A:public Y,public Z{}; 使用sizeof在vs210上计算上面类的大小,计算结果如下 可以看到empty virtual base class的大小并不是0,编译器会安插一个char,这样可以让两个object在内存中有独一无二的地址 X a,b; if(&a == &b) cerr<<"Memery

Virtual Memory PAGE TABLE STRUCTURE

COMPUTER ORGANIZATION AND ARCHITECTURE DESIGNING FOR PERFORMANCE NINTH EDITION The basic mechanism for reading a word from memory involves the translation of a virtual, or logical, address, consisting of page number and offset, into a physical addres

knockout 虚拟标签(virtual element) 在 table 中的问题

这几天看了MVC4 / 5 的一些东西, 基本上和 MVC 3都一样, 看起来毫不费力气, 项目还没有正式开工, 每天都是看文档,了解技术. 闲着无聊就把 knockout js 给看了一遍. 今天在看 SignalR的时候, 随手写了段测试代码,发现 Knockout 的虚拟标签有点问题, 一开始我是这样写的: <table> <tr data-bind="foreach:msgs"> <td data-bind="text:name"

《深度探索c++对象模型》chapter1关于对象对象模型

在c++中,有2种class data member:static和nostatic,以及3钟class member function:static,nostatic和virtual.已知下面这个class Point声明: class Point { public: Point(float xval); virtual ~Point(); float x() const; static int PointCount(); protected: virtual ostream& print(o

【C++对象模型】第一章 关于对象

1.C/C++区别 C++较之C的最大区别,无疑在于面向对象,C程序中程序性地使用全局数据.而C++采用ADT(abstract data tpye)或class hierarchy的数据封装.类相较于C的struct不仅只包含了数据,同时还包括了对于数据的操作.在语言层面上C++带来了很多面向对象的新特性,类.继承.多态等等.新特性使得C++更加强大,但同时却伴随着空间布局和存取时间的额外成本.这些额外成本主要由 virtual引起,包括: virtual function 机制,用来支持"执

c/c++笔记--5

1.假设derived类继承自base类,那么derived与base是一种“is  a”的关系,即derived类是base类,反之错误: 假设derived类虚继承自base类,那么derived与base是一种“has  a”的关系,即derived类有一个指向base类的vptr. 2.virtual base class的原始模型是在class object中为每一个有关联的virtual base class加上一个指针vptr, 该指针指向virtual基类表.有的编译器是在继承类

[转]《深度探索C++对象模型》读书笔记[一]

前 言 Stanley B.Lippman1.   任何对象模型都需要的三种转换风味: ü        与编译器息息相关的转换 ü        语言语义转换 ü        程序代码和对象模型的转换 2.   C++对象模型的两种解释 ü        语言中直接支持面向对象程序设计的部分 ü        对于各种支持的底层实现机制 3.   C++ class的完整virtual functions在编译时期就固定下来了,程序员没有办法在执行期动态增加或取代其中某一个.这使得虚拟函数调

深入探索C++对象模型-1

概述 在实际生产中,遇到一个复杂的类,如果能看出这个类的内存模型结构,那么以后的操作基本就没有难度的: 所以说,学会分析一个类的内存模型,是每一个C++程序员必须要会的知识. 下面,就让我们来了解C++对象模型! C++类封装和C中的结构体的区别 C++的类封装是在C语言中的结构体的基础上构建起来的,C结构体只允许存在数据,而不会存在对数据的操作. C++语言中延承C语言中的结构体,但增加的对数据的操作,即成员函数: 类是对结构体的进一步封装,使某些数据成员对外不可见,称为私有成员. 类和结构体

C++ virtual table pointer - vptr

To implement virtual functions, C++ uses a special form of late binding known as the virtual table. The virtual table is a lookup table of functions used to resolve function calls in a dynamic/late binding manner. The virtual table sometimes goes by