【发布时间】:2018-11-12 09:48:02
【问题描述】:
根据 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);
不仅空结构使对象膨胀(当多个这样的东西被继承时),而且结果取决于空结构的继承顺序。
【问题讨论】:
-
语言标准明确允许空基优化。 “它们的内存布局实际上取决于继承顺序”有点令人担忧,因为无法保证基类子对象的位置。你有一个你想要实现的例子吗?
-
您是否实际证明了这是您当前编译器的问题?我希望用作基类的空类不会在派生类中占用空间;一个具体的例子会很有帮助。
-
原因并不可怜。您只是没有真正引用它;真正的原因要复杂得多。标准可能没有这个限制(我不确定),但这需要一个复杂的证明来证明这总是会导致格式良好的程序。
-
改变继承顺序并不是一个微妙的改变。如果您的类型不是 POD,那么您的代码应该以这样的方式编写,即基类的命名顺序或 EBO 是否发生都无关紧要。当您关心内存布局时,您应该使用 POD 类型。出于所有意图和目的,不保证非 POD 类型。
-
我打赌你是在 MSVC 下编译的?这是多重继承的一个已知问题:connect.microsoft.com/VisualStudio/feedback/details/100686/… 解决方案包括不用担心,切换到“更好”的编译器,并避免多重继承。
标签: c++