【C++】 为什么C++空类占一个字节
00. 目錄
- 00. 目錄
- 01. 測試程序和結果分析
- 02. 單繼承空白基類最優化問題
- 03. 多繼承空白基類最優化問題
01. 測試程序和結果分析
測試程序如下:
#include <iostream>using namespace std;//聲明一個空類 class A{};int main(void) {//使用空類定義兩個對象A a1;A a2;cout << "sizeof(a1): " << sizeof(a1) << endl;cout << "sizeof(a2): " << sizeof(a2) << endl;cout << "&a1: " << &a1 << endl;cout << "&a2: " << &a2 << endl;return 0; }編譯和執行結果:
結果分析:
1) 其實這是C++中空類占位問題。
2) 在C++中空類會占一個字節,這是為了讓對象的實例能夠相互區別。具體來說,空類同樣可以被實例化,并且每個實例在內存中都有獨一無二的地址,因此,編譯器會給空類隱含加上一個字節,這樣空類實例化之后就會擁有獨一無二的內存地址。如果沒有這一個字節的占位,那么空類就無所謂實例化了,因為實例化的過程就是在內存中分配一塊地址。
注意:當該空白類作為基類時,該類的大小就優化為0了,這就是所謂的空白基類最優化。
02. 單繼承空白基類最優化問題
測試程序如下:
#include <iostream>using namespace std;//聲明一個空類 基類 class A{};//公有繼承 class B : public A { public:int a; };int main(void) {//使用空類定義兩個對象A a1;B b1;cout << "sizeof(a1): " << sizeof(a1) << endl;cout << "sizeof(b1): " << sizeof(b1) << endl;cout << "&a1: " << &a1 << endl;cout << "&b1: " << &b1 << endl;return 0; }編譯和執行結果如下:
現象分析:
在上例中,大部分編譯器對于sizeof(b1)的結果是4,而不是8。這就是所謂的空白基類最優化在(empty base optimization-EBO 或 empty base classopimization-EBCO)。在空基類被繼承后由于沒有任何數據成員,所以子類優化掉基類所占的1 byte。EBO并不是c++標準所規定必須的,但是大部分編譯器都會這么做。由于空基類優化技術節省了對象不必要的空間,提高了運行效率,因此成為某些強大技術的基石,基于類型定義類如stl中的binary_function、unary_function、iterator、iterator_traits的實現復用;基于策略類如內存管理、多線程安全同步的實現復用。當某個類存在空類類型的數據成員時,也可考慮借助EBO優化對象布局.
注意:空白基類最優化無法被施加于多重繼承上只適合單一繼承。
03. 多繼承空白基類最優化問題
測試程序:
#include <iostream>using namespace std;//聲明一個空類 基類 class A{};//聲明另外一個空類 基類 class B{};//公有繼承 class C : public A { public:int a; };class D : public A, public B { public:int a; };int main(void) {//使用空類定義兩個對象A a1;C c1;D d1;cout << "sizeof(a1): " << sizeof(a1) << endl;cout << "sizeof(c1): " << sizeof(c1) << endl;cout << "sizeof(d1): " << sizeof(d1) << endl;cout << "&a1: " << &a1 << endl;cout << "&c1: " << &c1 << endl;cout << "&d1: " << &d1 << endl;return 0; }編譯和執行結果:
1) Linux 64系統執行的結果:
2) Vs2015執行的結果
現象分析
該現象隨著編譯器不同可能不一樣
總結
以上是生活随笔為你收集整理的【C++】 为什么C++空类占一个字节的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Tools】CSDN-markdown
- 下一篇: 【C++】 C++虚函数表详细分析(上)