深刻理解類的填充規則

  struct/class中的成員變量所佔總大小不是簡單地將各個成員變量的大小相加,而是要考慮到讀取效率,有時須要添加填充字節。
  好比有些平臺每次讀都是從偶地址開始,若是一個int型(假設爲32位系統)若是存放在偶地址開始的地方,那 麼一個讀週期就能夠讀出這32bit,而若是存放在奇地址開始的地方,就須要2個讀週期,並對兩次讀出的結果的高低字節進行拼湊才能獲得該32bit數據。


  填充規則: (1)結構體變量的首地址可以被其最寬基本類型成員的大小所整除;
        (2)結構體每一個成員相對於結構體首地址的偏移量都是成員大小的整數倍,若有須要編譯器會在成員之間加上填充字節
        (3)結構體的總大小爲結構體最寬基本類型成員大小的整數倍,若有須要編譯器會在最末一個成員以後加上填充字節。


  判斷一個類的大小一般用到規則(2)和(3)。
例子1:基本分析
spa

class Coo {
    char c;
    short s;
    int i;
    short s2;
};

首先c的偏移量是0,而0是1的整數倍,所以不用加填充;s的偏移量是1,而1不是2的整數倍,所以要填充1;
i的偏移量是4,而4是4的整數倍,所以不用填充;s2的偏移量是8,而8是2的整數倍,所以不用填充。
最後,在類coo中,最寬基本類型是int,大小是4,而目前咱們的類大小爲: 1 (+1) + 2 + 4 + 2 = 10,不是4的整數倍,所以要在最後填充2。


例子2:空類
code

class Coo {};

空類的大小是1。若是coo的大小是0,就沒法區別其餘的空類了。


例子3:有靜態成員
blog

class Coo {
    static int i;
};

類的大小是1。靜態數據成員不屬於實例的一部分,而是放到了全局數據區。


例子4:類嵌套
ci

class CooIn {
    int i;
    short s;
    int i2;
};

class Coo{
    char c;
    CooIn ci;
    double d;
};

首先分析被嵌套的CooIn的大小,易得爲12,且最寬數據成員大小爲4。而後以ci爲分界點,前面的大小要爲4的整數倍,所以爲1 + 3,然後面
的分析就沒有什麼特殊性了。注意,不能把CooIn在Coo內展開爲
編譯器

class Coo{
    char c;
    int i;
    short s;
    int i2;
    double d;
};

要將CooIn看做一個總體,其傳輸單位爲4,所以ci前在加上CooIn時,要保證是4的整數倍    it

相關文章
相關標籤/搜索