c++多态情况下对象内存布局

原创 2016年08月31日 12:50:06

今天在复习C++多态时有个问题没弄清楚,子类继承含有虚函数的父类时,子类的虚表是否是公用的?
如果是公用的,虚表什么时候创建?为了弄清楚这个问题,写了以下程序来验证


得到了如下结论:
子类的虚表是公用,虚表创建于第一个实例构造之时,所有子类实例虚表指针都指向这块虚表。
同时也验证了C++对象的内存布局
以下是验证代码:

#include "stdafx.h"
#include<iostream>

using namespace std;

class A
{
public:
	virtual void a_function() {}
	int a = 1;
};
class B :public A
{
public:
	void a_function() {}
	int b = 2;
};

class C :public A
{
public:
	void c_function() {}
	int c = 3;
};

int main()
{
	A  a1;
	A  a2;
	B  b1;
	B  b2;
	C  c1;
	C  c2;

	cout << (int*)(&a1) << '\t' << (int *)(&a2) << '\n';//a对象虚表指针的地址,不同,存储在对象内存的起始处

	cout << *(int*)(&a1) << '\t'<< *(int *)(&a2)<<'\n'; //a对象虚表指针指向的值,相同即表示同一类的不同对象虚表指针指向同一块内存
	cout << *(int*)(&b1) <<'\t'<< *(int *)(&b2) << '\n'; //b对象虚表指针指向的值,相同即表示同一类的不同对象虚表指针指向同一块内存
	cout << *(int*)(&c1) << '\t' << *(int *)(&c2) << '\n'; //c对象虚表指针指向的值,相同即表示同一类的不同对象虚表指针指向同一块内存
	//a, b, c 三个类的虚表地址不同, C即使不含虚函数,也没重写a_function也继承了虚表指针。


	cout << (int*)(&b1)+1 << '\t' << (int *)(&b2)+1 << '\n';//不同b实例的b成员地址不同,表示不同实例分配了不同的内存


	cout << *((int*)(&b1) + 1) << '\t' << *((int *)(&b2) + 1) << '\n'; //b对象的第二个成员的值为继承自父类数据成员a的值(第一个成员为虚表指针)
	cout << *((int*)(&b1) + 2) << '\t' << *((int *)(&b2) + 2) << '\n'; //b对象第三个成员的值为子类数据成员b的值

	//综上继承时,如果父类有虚函数,内存布局如下:
	/*
	1、虚表指针,同一类虚表指针指向的值相同,即都指向同一块内存,同一张虚表
	2、父类的数据成员
	2、子类的数据成员
	*/

	//另外
	//当子类重写父类的虚函数时,子类的虚表对应的虚函数指针将被覆盖成子类的虚函数指针。
	//子类非继承自父类的虚函数,将被添加到虚表的末尾。
	//多重继承时,如果有n个含有虚函数的父类,则子类有n张虚表,每个实例起始处有n个虚表指针。
	//任何妄图使用父类指针想调用子类中的未覆盖父类的成员函数的行为都会被编译器视为非法。
    return 0;
}


结果如下图:


C++对象布局及多态实现探索之内存布局(整理的很多链接)

本文通过观察对象的内存布局,跟踪函数调用的汇编代码。分析了C++对象内存的布局情况,虚函数的执行方式,以及虚继承,等等 文章链接:http://dev.yesky.com/254/2191254.s...
  • u012138828
  • u012138828
  • 2014年08月26日 11:31
  • 358

C++对象模型之详述C++对象的内存布局

本文主要讨论继承对于对象的内存分布的影响,包括:继承后类的对象的成员的布局、继承对于虚函数表的影响、virtual函数机制如何实现、运行时类型识别等。由于在C++中继承的关系比较复杂,所以本文会讨论如...
  • ljianhui
  • ljianhui
  • 2015年06月08日 10:16
  • 5017

C++对象模型之简述C++对象的内存布局

在C++中,有两种类的成员变量:static和非static,有三种成员函数:static、非static和virtual。那么,它们如何影响C++的对象在内存中的分布呢? 当存在继承的情况下,其内存...
  • ljianhui
  • ljianhui
  • 2015年05月22日 02:28
  • 10017

面向对象_多态中的对象变化内存图解

/* */ class Animal{ public void eat(){ System.out.println("该吃饭了"); } } class Dog extends Anima...
  • L1585931143
  • L1585931143
  • 2016年10月06日 18:07
  • 387

C++虚继承(三) --- C++ 对象的内存布局(下)(陈皓)

C++ 对象的内存布局(下)   陈皓 http://blog.csdn.net/haoel     <<<点击这里查看上篇   重复继承   下面我们再来看看,发生重复继承的情况。所谓重复继承,也就...
  • liujiayu2
  • liujiayu2
  • 2016年03月18日 16:44
  • 335

C++ 对象的内存布局(多重虚拟继承)

原文:http://blog.csdn.net/haoel/article/details/3081328 下面,让我们来看看多重继承中C++对象的内存布局的情况,假设有下面这样一个类的继承关系...
  • hudashi
  • hudashi
  • 2016年06月28日 15:17
  • 258

OC的内存布局

转自:http://zhiwei.li/text/2012/03/objetive-c%E5%86%85%E5%AD%98%E5%B8%83%E5%B1%80/ 在 /usr/include...
  • zoutian007
  • zoutian007
  • 2013年06月26日 21:35
  • 797

【深入理解JVM】:Java对象的创建、内存布局、访问定位

对象的创建一个简单的创建对象语句Clazz instance = new Clazz();包含的主要过程包括了类加载检查、对象分配内存、并发处理、内存空间初始化、对象设置、执行ini方法等。主要流程如...
  • u011080472
  • u011080472
  • 2016年05月05日 12:06
  • 5216

c++构造函数中无法实现多态

今天简单写了个Factory Method,结果没有效果,很是纳闷。研究之后发现还是自己c++基础不牢固阿! #include class Factory {     public:   ...
  • fingding
  • fingding
  • 2011年09月21日 14:48
  • 2170

C++ 内存布局:深入理解C++内存布局

1、虚函数简介       虚函数的实现要求对象携带额外的信息,这些信息用于在运行时确定该对象应该调用哪一个虚函数。典型情况下,这一信息具有一种被称为vptr(virtual table point...
  • QQrenzai
  • QQrenzai
  • 2016年06月24日 10:36
  • 1725
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:c++多态情况下对象内存布局
举报原因:
原因补充:

(最多只允许输入30个字)