再談內存對齊問題

一個類的對象到底有多大?其大小由什麼因素影響?

我們假定這個類沒有繼承任何其他類,且沒有虛函數。先看下面例子:

#include <iostream>

using namespace std;

 

class Concrete

{

public:

         Concrete():val(0), c1('A'), c2('B')//, c3('C')

         {

         }

 

private:

         int val;

         char c1;

         char c2;

         //char c3;

};

 

int main(void)

{

         Concrete c;

         cout << sizeof(c) << endl;

 

return 0;

}

運行上面的程序,不管是否有成員變量c3,輸出結果均爲8,爲什麼呢?

由於內存的alignment的原因,所有對象的大小爲4bytes的整數倍(因爲其數據成員的數據類型最大佔用字節數爲4,即sizeof(int val) = 4),不足的就填充,如下面的圖示。

                                               

 

出現在derived class中的base class subobject保持其完成原樣性

#include <iostream>

using namespace std;

 

class Concrete1

{

private:

         int val;

         char c1;

public:

         inline Concrete1(int i, char c1) : val(i), c1(c1)

         {

         }

};

 

class Concrete2 : public Concrete1

{

private:

         char c2;

public:

         inline Concrete2(int i, char c1, char c2) : Concrete1(i, c1), c2(c2)

         {

         }

};

 

class Concrete3 : public Concrete2

{

private:

         char c3;

public:

         inline Concrete3(int i, char c1, char c2, char c3) : Concrete2(i, c1, c2), c3(c3)

         {

         }

};

 

int main(void)

{

         Concrete3 c(1, 'A', 'B', 'C');

         cout << sizeof(c) << endl;

 

return 0;

}

輸出會是多少呢?類Concrete3和1)中的類Concrete完成的功能一模一樣,但是Concrete3的對象的空間確變成了16bytes,比原來的整整多出一倍!原因就是C++語言保證“出現在derived class中的base class suboject有其完整性”。圖解如下:

 

 

在上圖中Concrete2類型的對象中,爲什麼也要填充3bytes呢?這還是因爲繼承了Concrete1的緣故。正是因爲繼承了Concrete1中的int val,因此Concrete2的對齊數變成了4 bytes,因此必須要填充3 bytes。總結如下:

其一,C++語言保證“出現在derived class中的base class suboject有其完整性”;

其二,derived class的對齊數 = min(指定的全局對齊數,max(base class的對齊數,derived class的對齊數))

 

 

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/pathuang68/archive/2009/04/24/4106016.aspx

發佈了50 篇原創文章 · 獲贊 1 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章