问题描述
大多数C ++程序员都知道空基类优化为 / 。 空的子类会发生什么?例如
class EmptyBase {
int i;
};
template< typename T>
class Derived:T {
};
std :: cout<< sizeof(Derived< EmptyBase>); //有这个标准的verdic吗?
与EBO类似,应该有一个EDO声明,因为派生类不会提供任何更多的成员,也不向其参数化类型引入任何虚拟的成员,它不应该需要更多的内存。考虑各种情况下,类似的东西可能apper(多继承,单继承...):
- 这样的优化标准/可能?
- 如果是,这种优化的机制是什么?是类似于?
注意:使用从其参数化类型派生的类模板是相当典型的。
标准本身不包含空基类案例。相反,它说(参见1.8):
和:
这从来没有说过,只有空基地适合任何种类的布局更改和离开有足够的空间用于挤压布局:例如:
struct A {}; struct B:A {int x; }; //equivalentto {int}
struct X {int a; }; struct Y:X {}; //等价于{int}
考虑 B b; code>和
Y y;
。可能的是 b
的地址, A
-subobject的 b
(即& static_cast< A&>(b)
)和 bx
是相同的,类似地, y
的地址, X
-suboject y
,并且 ya
的地址是相同的。
不工作是这样:
struct S {}; struct T {S s; }; //equivalentto {char}
code>我的意思是最明智的,节省空间的实现。
更有趣的情况如下:
struct Foo {int x; char a; }; // {int,char,char [3]}
struct Bar:Foo {short q; }; // {int,char,char,short}
此示例假设 (int)== 4
和 sizeof(short)== 2
。我们有 sizeof(Foo)== 8
为了对齐的原因,但 sizeof(Bar)
也是<$ c $
此标准的另一个相关部分是9.2 / 13:
标准布局类在开始没有填充,使得它们的地址等于它们的初始成员的地址。由于标准布局要求所有基本都是空的,或者最派生类本身没有数据成员,这意味着标准布局类必须使用一种空基优化,上面的 B
和 Y
的初始部分实际上是强制性的。
Most C++ programmers know about the empty base class optimazation as a technique/idiom. What happens with empty child classes? For example
class EmptyBase {
int i;
};
template<typename T>
class Derived : T {
};
std::cout << sizeof(Derived<EmptyBase>); // Is there a standard verdic on this?
Similarly to the EBO there should be an EDO stating that since a derived class doesn't provide any more members, nor introduces any virtual ones to its parametrizing type, it should not require more memory. Considering the various situations in which something like that might apper (multiple inheritance, single inheritance ...) :
- Is such an optimization standard/possible?
- If yes, what are the mechanics of such an optimization, are they similar to EBO's?
Note: Using class templates that derive from their parameterizing types is fairly typical. The topic is about space wasting in such situations
The standard does not contain an "empty base class" case per se. Rather, it says (cf. 1.8):
And:
And (Clause 9):
This never says that only empty bases are amenable to any kind of layout change and leaves ample room for "squeezing" the layout: for example:
struct A {}; struct B : A { int x; }; // "equivalent" to { int }
struct X { int a; }; struct Y : X {}; // "equivalent" to { int }
Consider B b;
and Y y;
. it is possible that the address of b
, that of the A
-subobject of b
(i.e. &static_cast<A&>(b)
) and that of b.x
are the same, and similarly that the address of y
, the X
-suboject of y
, and the address of y.a
are the same.
The only thing that does not work is this:
struct S {}; struct T { S s; }; // "equivalent" to { char }
By "equivalent"
I mean the most sensible, space-saving implementation.
A more interesting case is the following:
struct Foo { int x; char a; }; // { int, char, char[3] }
struct Bar : Foo { short q; }; // { int, char, char, short }
This example assumes sizeof(int) == 4
and sizeof(short) == 2
. We have sizeof(Foo) == 8
for alignment reasons, but sizeof(Bar)
is also 8
despite having more data members.
Another relevant part of the standard is 9.2/13:
Finally, 9.2/10 says that standard-layout classes have no padding at the beginning, so that their address equals the address of their "initial member". Since standard-layout requires that all bases either be empty, or that the most-derived class itself have no data members, this means that standard-layout classes must employ a kind of "empty base" optimization, and the initial part of the layout of my B
and Y
above is actually mandatory.
这篇关于空派生优化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!