為什么空類大小是一
我們可能都知道,C++中空類的大小是1。
- #include <iostream>
- class EmptyA {};
- int main() {
- std::cout << "sizeof EmptyA " << sizeof(EmptyA) << std::endl;
- return 0;
- };
結(jié)果如下:
- sizeof EmptyA 1
然而在C語言中空結(jié)構(gòu)體的大小是0,空結(jié)構(gòu)體大小是0我們貌似可以理解,但為什么到C++中,空類的大小卻是1呢?
原因如下:
實(shí)際上,這是類結(jié)構(gòu)體實(shí)例化的原因,空的類或結(jié)構(gòu)體同樣可以被實(shí)例化,如果定義對空的類或者結(jié)構(gòu)體取sizeof()的值為0,那么該空的類或結(jié)構(gòu)體實(shí)例化出很多實(shí)例時(shí),在內(nèi)存地址上就不能區(qū)分該類實(shí)例化出的實(shí)例,所以,為了實(shí)現(xiàn)每個(gè)實(shí)例在內(nèi)存中都有一個(gè)獨(dú)一無二的地址,編譯器往往會給一個(gè)空類隱含的加一個(gè)字節(jié),這樣空類在實(shí)例化后在內(nèi)存得到了獨(dú)一無二的地址,所以空類所占的內(nèi)存大小是1個(gè)字節(jié)。
實(shí)際上,這不是本文的重點(diǎn),重點(diǎn)其實(shí)是想向大家分享一下C++中的空基類優(yōu)化(EBO)技術(shù)。
直接看代碼:
- #include <iostream>
- class EmptyA {};
- class A {
- int a;
- };
- class B : public EmptyA {
- int b;
- };
- class D : public A {
- int d;
- };
- class C {
- int c;
- EmptyA d;
- };
- int main() {
- std::cout << "sizeof EmptyA " << sizeof(EmptyA) << std::endl;
- std::cout << "sizeof B " << sizeof(B) << std::endl;
- std::cout << "sizeof C " << sizeof(C) << std::endl;
- std::cout << "sizeof A " << sizeof(A) << std::endl;
- std::cout << "sizeof D " << sizeof(D) << std::endl;
- return 0;
- };
結(jié)果如下:
- sizeof EmptyA 1
- sizeof B 4
- sizeof C 8
- sizeof A 4
- sizeof D 8
這里:
- 空類EmptyA的大小是1,上面已經(jīng)介紹過。
- 類C的大小是8,因?yàn)閕nt占四個(gè)字節(jié),EmptyA占1個(gè)字節(jié),再加上字節(jié)對齊,編譯器補(bǔ)了4個(gè)字節(jié),最后就是8。
- 類A的大小是4,沒啥毛病。
- 類D的大小是8,因?yàn)閕nt占4個(gè)字節(jié),繼承的A類也占4個(gè)字節(jié),最后就是8。
可以看到,類B的大小是4。
為什么同樣是繼承。類D把類A的大小繼承了下來。而類B的大小卻是4,為什么沒有把EmptyA的大小繼承下來呢?
這就是本文想分享的空基類優(yōu)化(EBO)技術(shù)。具體其實(shí)上面的示例已經(jīng)很清楚了,就是子類如果繼承空類,并不會產(chǎn)生額外的大小,它的大小還是子類本身的大小。
EBO技術(shù)有什么作用?
我們普通開發(fā)者可能認(rèn)為多那一兩個(gè)字節(jié)沒什么大不了的,但是在STL中,在精益求精、寸土必爭的委員會大佬們那里,這至關(guān)重要,再貼下EBO在STL中的作用。
- template<typename _Tp, _Tp __v>
- struct integral_constant {
- static constexpr _Tp value = __v;
- typedef _Tp value_type;
- typedef integral_constant<_Tp, __v> type;
- };
- typedef integral_constant<bool, true> true_type;
- typedef integral_constant<bool, false> false_type;
- template<>
- struct __is_floating_point_helper<float>
- : public true_type { };
- template<>
- struct __is_floating_point_helper<double>
- : public true_type { };
STL中各種空類繼承,如果繼承空類會給子類產(chǎn)生額外的大小,那還了得?
我們可能平時(shí)用不到EBO技術(shù),但還是建議了解,說不上哪天可以和面試官裝一波呢。
打完收工。