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

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

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指针。

时间: 2016-11-07

vs2008下C++对象内存布局(2):简单继承的相关文章

vs2008下C++对象内存布局(3):加上虚函数

这次我们为父类加上虚函数: class CParent { public: int parent_a; int parent_b; public: virtual void parent_f1() { parent_a = 0x10; } virtual void parent_f2() { parent_b = 0x20; } }; class CChild : public CParent { public: int child_a; int child_b; public: virtual

vs2008下C++对象内存布局(5):vtbl

再看看vtbl的其它内容,先写段代码: class CParent { public: int parent_a; int parent_b; public: virtual void parent_f1() {} virtual void parent_f2() {} public: void parent_f3() {} void parent_f4() {} }; class CChild : public CParent { public: int child_a; int child_

vs2008下C++对象内存布局(6):指向成员函数的指针

Vs支持指向成员函数的指针,沿用上文中的类进行试验: class CParentA { public: int parenta_a; int parenta_b; public: virtual void parenta_f1() {this->parenta_a = 0x10;} virtual void parenta_f2() {this->parenta_a = 0x20;} public: void parenta_f3() {this->parenta_a = 0x30;}

vs2008下C++对象内存布局(4):多重继承

这回我们考虑多重继承的情况: class CParentA { public: int parenta_a; int parenta_b; public: virtual void parenta_f1() { parenta_a = 0x10; } virtual void parenta_f2() { parenta_b = 0x20; } }; class CParentB { public: int parentb_a; int parentb_b; public: virtual vo

对象内存布局 (14)

前言 07年12月,我写了一篇<C++虚函数表解析>的文章,引起了大家的兴趣.有很多朋友对我的文章留了言,有鼓励我的,有批评我的,还有很多问问题的.我在这里一并对大家的留言表示感谢.这也是我为什么再写一篇续言的原因.因为,在上一篇文章中,我用了的示例都是非常简单的,主要是为了说明一些机理上的问题,也是为了图一些表达上方便和简单.不想,这篇文章成为了打开C++对象模型内存布局的一个引子,引发了大家对C++对象的更深层次的讨论.当然,我之前的文章还有很多方面没有涉及,从我个人感觉下来,在谈论虚函数

对象内存布局 (11)

注意:关于内存对齐(memory alignment),请看关于内存对齐问题,后面将会用到.   下面我们进行在普通继承(即非虚继承)时,派生类的指针转换到基类指针的情形研究.假定各类之间的关系如下图:   代码如下: #include <iostream> using namespace std; class Parent { public: int parent; }; class Child : public Parent { public: int child; }; class Gr

对象内存布局 (7)

在对象内存布局 (5)的代码中,在Derived类中覆盖Base1中声明的vfBase1_1(),其他代码不变.修改后的代码如下: #include <iostream> using namespace std; class Base1 { public: int m_base1; inline virtual void vfBase1_1() { cout << "This is in Base1::vfBase1_1()" << endl; }

对象内存布局 (6)

如果在对象内存布局 (5)的代码中,将Base1中的两个虚函数声明删除,同时将main函数中的下面代码注释掉(因为现在只有两张虚函数表了): 代码如下: #include <iostream> using namespace std; class Base1 { public: int m_base1; /*inline virtual void vfBase1_1() { cout << "This is in Base1::vfBase1_1()" <

对象内存布局 (12)

下面来看看虚基类对对象内存布局的影响.虚基类的主要作用就是在所有的派生类中,保留且仅保留一份虚基类的suboject.   a. 一个虚基类的情况 #include <iostream> using namespace std; class Base { public: int base_member; }; class Derived : public virtual Base {}; int main(void) { Base b; Derived d; cout << siz