[英]Empty derived optimization
大多數C ++程序員都知道空基類優化是一種技術 / 習慣用法 。 空子類會怎樣? 例如
class EmptyBase {
int i;
};
template<typename T>
class Derived : T {
};
std::cout << sizeof(Derived<EmptyBase>); // Is there a standard verdic on this?
與EBO相似,應該有一個EDO聲明, 由於派生類不再提供任何成員,也不向其參數化類型引入任何虛擬成員 ,因此它不需要更多的內存。 考慮到可能發生類似情況的多種情況(多重繼承,單一繼承...):
注意:使用從其參數化類型派生的類模板是非常典型的。 主題是關於在這種情況下的空間浪費
該標准本身不包含“空基類”案例。 相反,它說(參見1.8):
[A]大多數派生對象的大小應為非零,並應占用一個或多個字節的存儲空間。 基類子對象的大小可以為零。
和:
除非一個對象是零大小的基類子對象,否則該對象的地址就是它占據的第一個字節的地址。 daccess-ods.un.org daccess-ods.un.org如果一個對象是另一個的子對象,或者至少一個是零大小的基類子對象並且它們是不同類型,則兩個對象可能具有相同的地址。 否則,它們應具有不同的地址。
並且(第9條):
類類型的完整對象和成員子對象的大小不得為零。 腳注:基類的子對象不受此限制。
這從來沒有說過只有空的底座才能進行任何形式的布局更改,並且為“擠壓”布局留出了足夠的空間:例如:
struct A {}; struct B : A { int x; }; // "equivalent" to { int }
struct X { int a; }; struct Y : X {}; // "equivalent" to { int }
考慮B b;
和Y y;
。 可能的是,地址b
,所述的A
的-subobject b
(即&static_cast<A&>(b)
和該bx
是相同的,並且類似地那的地址y
中, X
的-suboject y
,和ya
的地址相同。
唯一不起作用的是:
struct S {}; struct T { S s; }; // "equivalent" to { char }
"equivalent"
是指最明智,節省空間的實現。
一個更有趣的情況如下:
struct Foo { int x; char a; }; // { int, char, char[3] }
struct Bar : Foo { short q; }; // { int, char, char, short }
本示例假定sizeof(int) == 4
和sizeof(short) == 2
。 出於對齊原因,我們的sizeof(Foo) == 8
,但是盡管有更多的數據成員, sizeof(Bar)
也為8
。
該標准的另一個相關部分是9.2 / 13:
分配具有相同訪問控制(條款11)的(非聯盟)類的非靜態數據成員,以便以后的成員在類對象中具有更高的地址。 未指定具有不同訪問控制的非靜態數據成員的分配順序(11)。 實施一致性要求可能會導致兩個相鄰成員不能彼此立即分配; 管理虛擬功能(10.3)和虛擬基類(10.1)的空間要求也可能如此。
最后,9.2 / 10說標准布局類在開始時沒有填充,因此它們的地址等於其“初始成員”的地址。 由於標准布局要求所有基數都為空,或者最派生的類本身沒有數據成員,因此這意味着標准布局類必須采用一種“空基”優化,以及布局的初始部分實際上,我上面的B
和Y
是必須的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.