[英]Zero-sized struct
根据C ++标准(继承自C),空结构仍然具有非零大小。 这个(可怜的恕我直言)的原因是两个不同的变量应该有不同的地址。 现在,继承一个空结构并不总是“膨胀”该对象。 但在某些情况下情况就是这样。
我有一个相当复杂的类架构,涉及激烈的模板巫术。 结果,最后的类(我需要创建的实例)可能有几个继承的空结构。 由于这个事实,他们中的一部分最终可能会被夸大。 最糟糕的是,他们的内存布局实际上取决于继承的顺序。
如果有可能的话,我想摆脱这一切。
是否有一个C ++编译器可以配置为消除这种空间浪费,实际上是打破标准的代价?
编辑:
我是说这个:
struct Empty1 {};
struct Empty2 {};
struct NonEmpty {
int Value;
};
struct MyClass1
:public NonEmpty
,public Empty1
,public Empty2
{
};
struct MyClass2
:public Empty1
,public NonEmpty
,public Empty2
{
};
struct MyClass3
:public Empty1
,public Empty2
,public NonEmpty
{
};
STATIC_ASSERT(sizeof(MyClass1) == 8);
STATIC_ASSERT(sizeof(MyClass2) == 4);
STATIC_ASSERT(sizeof(MyClass3) == 8);
不仅空结构会使对象膨胀(当多个这样的东西继承时),而且结果还取决于空结构的继承顺序。
空基优化是允许空基不要“膨胀”对象的东西,就像你调用它一样。 但是,您必须小心,以便对象不会从同一个空基继承两次,否则将不允许此优化。 避免这种情况的一种方法是对空基础进行模板化,实例化它们,以便不会多次继承相同的空模板实例。
如果您的基类用于标记具体类,那么您可以考虑将您的设计更改为非侵入式设计。
在大多数现代c ++编译器中,您会发现:
struct a { }; // empty struct
struct b : a { int x}; // inherits from empty struct.
assert(sizeof(b)==sizeof(int)); // despite sizeof(a) >0
这实际上是否能缓解您的顾虑?
是否有可以配置的C ++编译器来消除这种空间浪费,......
是。 GCC-4.3.4
......实际上打破了标准的代价?
不,该标准允许您期望的行为。
g ++支持零大小数组,您可以使用以下之一:
struct Empty1 {
int dummy[0];
};
要么
struct Empty2 {
int dummy[];
};
只有在使用'-pedantic'标志时,它才会生成警告。
如果您已经说过,它将具有与同一对象中相同类型的另一个实例相同的地址,则基类可以是非零大小。
要“解决”这个问题,你需要确保你继承另一个类的空类或结构没有任何共同的祖先。
或者您可以自己手动布置类,但听起来您正在执行类似于从DirectX顶点声明枚举创建DirectX顶点类型的操作,因此这实际上没有帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.