`
xiaoer_1982
  • 浏览: 1812272 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

vs2008下C++对象内存布局(2):简单继承

阅读更多

快乐虾

http://blog.csdn.net/lights_joy/

lights@hb165.com

本文适用于

Xp sp3

Vs2008

欢迎转载,但请保留作者信息

这次我们添加一个子类,父类和子类均不带虚函数:

class CParent

{

public:

int parent_a;

int parent_b;

public:

void parent_f1()

{

parent_a = 0x10;

}

void parent_f2()

{

parent_b = 0x20;

}

};

class CChild : public CParent

{

public:

int child_a;

int child_b;

public:

void child_f1()

{

child_a = 0x30;

}

void child_f2()

{

child_b = 0x40;

}

};

1.1.1 内存布局

先给这些成员变量赋几个值:

child.parent_a = 1;

0041138E C7 05 50 71 41 00 01 00 00 00 mov dword ptr [child (417150h)],1

child.parent_b = 2;

00411398 C7 05 54 71 41 00 02 00 00 00 mov dword ptr [child+4 (417154h)],2

child.child_a = 3;

004113A2 C7 05 58 71 41 00 03 00 00 00 mov dword ptr [child+8 (417158h)],3

child.child_b = 4;

004113AC C7 05 5C 71 41 00 04 00 00 00 mov dword ptr [child+0Ch (41715Ch)],4

观察&child所指的内存区内容:

0x00417150 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 ................

很明显,VS将父类和子类的数据成员合并到同一块内存区域,但是同样没有往里面加额外的东西,&child指针将指向第一个成员parent_a

1.1.2 函数调用

观察函数调用:

child.parent_f1();

00411840 B9 50 71 41 00 mov ecx,offset child (417150h)

00411845 E8 78 F9 FF FF call CParent::parent_f1 (4111C2h)

child.child_f1();

0041184A B9 50 71 41 00 mov ecx,offset child (417150h)

0041184F E8 64 F9 FF FF call CChild::child_f1 (4111B8h)

和简单父类的函数调用没什么两样。用ECX传递this指针。

1.1.3 变量覆盖

在子类里添加两个和父类同名的成员变量:

class CChild : public CParent

{

public:

int child_a;

int child_b;

int parent_a;

int parent_b;

………

再执行前面的赋值语句:

child.parent_a = 1;

0041180E C7 05 04 75 41 00 01 00 00 00 mov dword ptr [child+10h (417504h)],1

child.parent_b = 2;

00411818 C7 05 08 75 41 00 02 00 00 00 mov dword ptr [child+14h (417508h)],2

child.child_a = 3;

00411822 C7 05 FC 74 41 00 03 00 00 00 mov dword ptr [child+8 (4174FCh)],3

child.child_b = 4;

0041182C C7 05 00 75 41 00 04 00 00 00 mov dword ptr [child+0Ch (417500h)],4

可以发现赋值时使用的偏移量发生了变化,观察&child所在的内存区:

0x004174F4 00 00 00 00 00 00 00 00 03 00 00 00 04 00 00 00 ................

0x00417504 01 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 ................

可以看到合并后的内存有6个整数,且对child.parent_a的赋值其实是对子类的成员进行赋值。

而当我们用下面的赋值语句时:

pparent = &child;

00412E44 C7 05 E4 74 41 00 F4 74 41 00 mov dword ptr [pparent (4174E4h)],offset child (4174F4h)

pparent->parent_a = 1;

00412E4E A1 E4 74 41 00 mov eax,dword ptr [pparent (4174E4h)]

00412E53 C7 00 01 00 00 00 mov dword ptr [eax],1

pparent->parent_b = 2;

00412E59 A1 E4 74 41 00 mov eax,dword ptr [pparent (4174E4h)]

00412E5E C7 40 04 02 00 00 00 mov dword ptr [eax+4],2

从偏移量就可以看出它是对父类的成员进行赋值。

1.1.4 函数覆盖

在子类里面添加一个和父类同名的函数,再进行函数调用:

pchild = &child;

00412E26 C7 05 F0 74 41 00 F4 74 41 00 mov dword ptr [pchild (4174F0h)],offset child (4174F4h)

pchild->parent_f1();

00412E30 8B 0D F0 74 41 00 mov ecx,dword ptr [pchild (4174F0h)]

00412E36 E8 9B E3 FF FF call CChild::parent_f1 (4111D6h)

pparent = &child;

00412E3B C7 05 E4 74 41 00 F4 74 41 00 mov dword ptr [pparent (4174E4h)],offset child (4174F4h)

pparent->parent_f1();

00412E45 8B 0D E4 74 41 00 mov ecx,dword ptr [pparent (4174E4h)]

00412E4B E8 72 E3 FF FF call CParent::parent_f1 (4111C2h)

从反汇编的结果可以明显看出使用父类指针和使用子类指针调用同名函数时的差异。

2 参考资料

vs2008C++对象内存布局(1(2009-9-9)

分享到:
评论

相关推荐

    C++ 内存对象布局

    涉及各种情况下C++对象的sizeof大小,包括单一类对象,继承,重复继承 多继承 单一虚继承 等各种情况下的对象大小。对C++对象内存布局有清楚了解。

    (转)C++_对象的内存布局

    1)有成员变量的情况。 2)有重复继承的情况。 3)有虚拟继承的情况。 4)有钻石型虚拟继承的情况。

    C++对象模型在内存中的实现

    C++对象模型在内存中的实现,讲述了类,继承以及虚继承的内存布局;成员变量和成员函数的访问已经访问时的开销情况,包含虚函数的情况,考察构造函数,析构函数,以及特殊的赋值操作符成员函数是如何工作的,数组是...

    c++继承中的内存布局

    c++继承中的内存布局,c++高手必读,学习com,boost,面向对象必须了解,多重继承等

    类的对象的内存布局

    这是一些关于基类含有virtual函数或子类是virtual继承的对象的内存布局。其中有我截的一些图、内存布局图、文字说明,不过能力有限,说的不是很清楚,望谅解

    C++ 对象的内存布局(上)1

    -) 对象的影响因素 简而言之,我们一个类可能会有如下的影响因素: 1)成员变量2)虚函数(产生虚函数表)3)单一继承(只继承于一个类)4)多重继承(继承多个类

    深度探索模C++对象模型PDF

    C++对象模型(Th e C++ Object Model) 对象模型如何影响程序(How the Object Model Effects Programs) 1.2 关键词所带来的差异(A Keyword Distinction) 关键词的困扰 策略性正确的struct(The Politically ...

    深度探索C++对象模型 超清版

    C++对象模型(Th e C++ Object Model) 对象模型如何影响程序(How the Object Model Effects Programs) 1.2 关键词所带来的差异(A Keyword Distinction) 关键词的困扰 策略性正确的struct(The Politically ...

    浅谈C++中派生类对象的内存布局

    主要从三个方面来讲: ...实际内存布局由编译器自己决定,VS里,把虚指针放在最前边,接着是基类的Object,最后是派生类自己的object。举个栗子: class A { int b; char c; }; class A1 :public A { char a; }; i

    C++对象的内存布局

    不想,这篇文章成为了打开C++对象模型内存布局的一个引子,引发了大家对C++对象的更深层次的讨论。当然,我之前的文章还有很多方面没有涉及,从我个人感觉下来,在谈论虚函数表里,至少有以下这些内容没有涉及:1)...

    关于C++对象继承中的内存布局示例详解

    本文给大家介绍的是关于C++对象继承的内存布局的相关内容,分享出来供大家参考学习,在开始之前说明下,关于单继承和多继承的简单概念可参考此文章 以下编译环境均为:WIN32+VS2015 虚函数表 对C++ 了解的人都应该...

    C++菱形继承分析

    C++菱形继承对象构造部分分析和虚表内存布局,附件包括了源码和二进制文件

    《深度探索C++对象模型》(Stanley B·Lippman[美] 著,侯捷 译)

    本书重点:探索“对象导向程序所支持的C++对象模型”下的程序行为。对于“对象导向性质之基础实现技术”以及“各种性质背后的隐含利益交换”提供一个清楚的认识。检验由程序变形所带来的效率冲击。提供丰富的程序...

    Inside C++ mode

    C++的经典之作,弄清C++对象的内存布局,对于多重继承和COM学习有很大的帮助

    多重继承及虚继承中对象内存的分布

    本文我们将阐释GCC编译器针对多重继承和虚拟继承下的对象内存布局。尽管在理想的使用环境中,一个C++程序员并不需要了解这些编译器内部实现细节,实际上,编译器针对多重继承(特别是虚拟继承)的各种实现细节对于我们...

    C++编程思想习题

    3.4对象布局 3.5类 3.5.1用存取控制来修改stash 3.5.2用存取控制来修改stack 3.6句柄类(handleclasses) 3.6.1可见的实现部分 3.6.2减少重复编译 3.7小结 3.8练习 第4章 初始化与清除 4.1用构造函数确保初始化 4.2...

Global site tag (gtag.js) - Google Analytics