大小结构
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顶点类型,所以这并没有真正的帮助。
- 如何循环打印顶点结构
- 通过方法访问结构
- 使用不带参数的函数访问结构元素
- 预处理器:插入结构名称中的前一个行号
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 孤立代码块在结构中引发异常
- 有什么方法可以遍历结构吗
- 如何在 C# 中映射双 C 结构指针?
- 如何在C++中使用结构生成映射
- 无法将结构注册为增强几何体3D点
- 多成员Constexpr结构初始化
- C++将文本文件中的数据读取到结构数组中
- 如何重构类层次结构以避免菱形问题
- 如何在C++中序列化结构数据
- std::vector的包装器,使数组的结构看起来像结构的数组
- 没有为自己的结构调用列表推回方法
- 奇怪的结构&GCC&clang(void*返回类型)
- 在 c++ 中拥有一组结构的正确方法是什么?
- vscode g++链路故障:体系结构x86_64的未定义符号
- C++概念:如何使用'concept'检查模板化结构的属性?