各种继承内存布局(虚表)

虚继承

  1. 内存布局:Base1,Base2各自有自己的虚表,因为自己类中有自己的虚函数。
#include<iostream>
using namespace std;
typedef void(*Fun)();
class Base
{
public:
	virtual void fun1()
	{
		cout << "Base::fun1()" << endl;
	}

public:
	int _b;
};
class Base1 :virtual public Base
{
public:
	virtual void fun1()
	{
		cout << "Base1::fun1()" << endl;
	}
	virtual void fun3()
	{
	}
public:
	int _b1;
};
class Base2 :virtual public Base
{
public:
	virtual void fun1()
	{
		cout << "Base2::fun1()" << endl;
	}
	virtual void fun2()
	{
	}
public:
	int _b2;
};
class Derive :public Base1, public Base2
{
public:
	virtual void fun1()
	{
		cout << "Derive::fun1()" << endl;
	}
public:
	int _d;
};
void PrintVTable(int *ptr)
{
	for (int i = 0; ptr[i] != 0; ++i)
	{
		Fun f = (Fun)ptr[i];
		f();
	}
}
int main()
{
	Derive b1;
	b1._b1 = 2;
	b1.Base1::_b = 1;
	b1._b2 = 3;
	b1._d = 4;
	/*int *p1=(int *)(*(int*)&b1);
	PrintVTable(p1);

	cout<<sizeof(Base1)<<endl;
	int *p2=(int*)(*(int*)((int)&b1+sizeof(Base1)));
	PrintVTable(p2);*/
	system("pause");
	return 0;
}

2.子类中有虚函数,所以父类中必须创建虚表指针

class Base1 :virtual public Base

{

public:

virtual void fun1()

{

cout << "Base1::fun1()" << endl;

}

public:

int _b1;

};

class Base2 :virtual public Base

{

public:

virtual void fun1()

{

cout << "Base2::fun1()" << endl;

}

public:

int _b2;

};

class Derive :public Base1, public Base2

{

public:

virtual void fun1()

{

cout << "Derive::fun1()" << endl;

}

virtual void fun2()

{

}

public:

int _d;

};

3.父类中无虚函数,在子类中创建虚表指针

class Base

{

public:

public:

int _b;

};

class Base1 :virtual public Base

{

public:

virtual void fun1()

{

cout << "Base1::fun1()" << endl;

}

public:

int _b1;

};

class Base2 :virtual public Base

{

public:

virtual void fun1()

{

cout << "Base2::fun1()" << endl;

}

public:

int _b2;

};

class Derive :public Base1, public Base2

{

public:

virtual void fun1()

{

cout << "Derive::fun1()" << endl;

}

virtual void fun2()

{

}

public:

int _d;

};

时间: 2024-08-06 20:42:04

各种继承内存布局(虚表)的相关文章

c/c++: c++继承 内存分布 虚表 虚指针 (转)

http://www.cnblogs.com/DylanWind/archive/2009/01/12/1373919.html 前部分原创,转载请注明出处,谢谢! class Base { public:  int m_base; }; class DerivedA: public Base { public:  int m_derivedA; }; class DerivedB: public Base { public:  int m_derivedB; }; class DerivedC

【转】c++继承中的内存布局

今天在网上看到了一篇写得非常好的文章,是有关c++类继承内存布局的.看了之后获益良多,现在转在我自己的博客里面,作为以后复习之用. ——谈VC++对象模型(美)简.格雷程化    译 译者前言 一个C++程序员,想要进一步提升技术水平的话,应该多了解一些语言的语意细节.对于使用VC++的程序员来说,还应该了解一些VC++对于C++的诠释. Inside the C++ Object Model虽然是一本好书,然而,书的篇幅多一些,又和具体的VC++关系小一些.因此,从篇幅和内容来看,译者认为本文

C++各种类继承关系的内存布局

body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; border-width: 2px 0 2px 0;} th{border: 1px solid gray; padding: 4px; background-color: #DDD;} td{border: 1px solid gray; padding: 4px;} tr:nth-child(

C++ 无虚函数的单继承内存模型

C++类因为有继承的存在要比C时代的struct复杂得一些,特别是加上有虚函数的时候,以及多继承等这些特性更是令其内存布局变得面目全非.说实在的我也把握不了,我只是在一个实际的平台上进行了一些探索而已,并用此篇笔记将我的探索成果记录下来. 虽然说有些东西在C++标准里面没有规定如何做,不同的实现可能会有不同的作法,但是了解一个实际的系统是如何做的也会有益于我们更加深入的了解C++或者举一反三地理解其他的实现,而且如果我们了解了自己所用的系统上的具体实现的话,就可以对其为所欲为. 没有虚函数单继承

虚继承的内存布局手札1——基于VS2012

1.纸上得来总觉浅,低头debug才深刻. 对于<深度探索C++对象模型>这类型的书,得到的知识要去及时巩固才能实现永久记忆. 2.在实现了了虚拟继承归并分支之后的内容布局跟虚表的可复用存在极大关系. 继承的顺序决定了A和B的布局顺序,然后Common则在高地址,即公虚基类的布局放在D的尾部. 情况1: class A:public virtual Common{...}; class B:public virtual Common{...;virtual void NotInCommon()

虚继承之单继承的内存布局(VC在编译时会把vfptr放到类的头部,这和Delphi完全一致)

C++2.0以后全面支持虚函数与虚继承,这两个特性的引入为C++增强了不少功能,也引入了不少烦恼.虚函数与虚继承有哪些特性,今天就不记录了,如果能搞了解一下编译器是如何实现虚函数和虚继承,它们在类的内存空间中又是如何布局的,却可以对C++的了解深入不少.这段时间花了一些时间了解这些玩意,搞得偶都,不过总算有些收获,嘿嘿. 先看一段代码class A{      virtual aa(){};}; class B : public virtual  A{      char j[3];      

虚表结构与虚继承内存对象模型

最近看了下Inside C++里面讲的对虚继承层次的对象的内存布局,发现在不同编译器实现有所区别.因此,自己动手探索了一下.结果如下: 首先,说说GCC的编译器. 它实现比较简单,不管是否虚继承,GCC都是将虚表指针在整个继承关系中共享的,不共享的是指向虚基类的指针. class A { int a; virtual ~A(){} }; class B:virtual public A{ virtual ~B(){} virtual void myfunB(){} }; class C:virt

面向对象--多继承&amp;派生类对象内存布局分析&amp;各基类指针所指向的位置分析

背景 原文链接:ordeder  http://blog.csdn.net/ordeder/article/details/25477363 关于非虚函数的成员函数的调用机制,可以参考: http://blog.csdn.net/yuanyirui/article/details/4594805 成员函数的调用涉及到面向对象语言的反射机制. 虚函数表机制可以查看下面这个blog: http://blog.csdn.net/haoel/article/details/1948051 总结为: 其一

C++ 对象的内存布局—— 虚继承下的虚函数

C++ 对象的内存布局(下)这篇文章的"单一虚拟继承"和"钻石型虚拟继承"时的类内存布局讲得不太清楚,我有一处疑问,我用的是VS2005.因此记录一下. 类继承图例如以下: 这里:类B被类B1和B2虚拟继承,而B1和B2同一时候被D继承. B1的f().B2的f()覆盖了B的f(): D的f()覆盖了B1的f(),D的f1()覆盖了B1的f1() D的f()覆盖了B2的f(),D的f2()覆盖了B2的f2() 类代码例如以下: class B { public: i