为什么由两个空class导出的空class的大小是2?
Why the size of empty class that is derived from two empty classes is 2?
我知道空class的大小为1只是为了符合不允许对象(及其classes)大小为0的标准。这里,我我得到派生 class D 的大小为 2。为什么在这种情况下行为不同
假设没有从class B和C继承到D的数据成员或虚拟指针?
#include<iostream>
using namespace std;
class A {};
class B : public A {};
class C : public A {};
class D : public B, public C {};
int main() {
cout<<"Size of D is: "<<sizeof(D)<<endl;
return 0;
}
对我来说,空碱基优化是否可以应用在这里,取决于人们如何解释 [intro.object/8]:
Unless an object is a bit-field or a base class subobject of zero
size, the address of that object is the address of the first byte it
occupies. Two objects a and b with overlapping lifetimes that are not
bit-fields may have the same address if one is nested within the
other, or if at least one is a base class subobject of zero size and
they are of different types; otherwise, they have distinct addresses.
B
和C
是不同的类型吗?他们都是A
。实际上是两个不同的 A
对象。编译器编写者可以在此处停止分别为 B
和 C
分配存储空间,而无需检查 A
是否为空。
值得注意的是,如果您有 B
和 C
继承自 separate 基础,则使用 g++ 时大小会返回 1:
#include<iostream>
class A {};
class A1 {};
class B : public A {};
class C : public A1 {};
class D : public B, public C {};
int main() {
std::cout << "Size of D is: " << sizeof(D) << std::endl;
return 0;
}
这是因为您继承自两个基 class,它们本身派生自相同的基 class A
,看看当您更改程序时输出如何变化对此
#include<iostream>
using namespace std;
class A {};
class Z {};
class B : public A {};
class C : public Z {};
class D : public B, public C {};
int main() {
cout<<"Size of D is: "<<sizeof(D)<<endl;
return 0;
}
如您所见,D
的大小为 1
该问题与您可能知道的可怕钻石的问题类似。编译器试图消除示例中 D
中 A
的两个实例的歧义。并且这里没有应用空基优化,标准没有要求,编译器也没有实现(见下文)
该标准明确允许编译器不对多继承情况应用空基优化。相关引用自标准 here
Allowing standard-layout classes to have base classes forces compilers to implement the empty base optimization for standard-layout classes, and this could break a compiler's application binary interface (ABI). See 9.2/18 above. This is believed not to be a concern for modern compilers, except possibly in the case of multiple inheritance. Since multiple inheritance is not central to this proposal, allowing standard-layout classes or their bases to use multiple inheritance will be eliminated from the proposal if it proves contentious.
我知道空class的大小为1只是为了符合不允许对象(及其classes)大小为0的标准。这里,我我得到派生 class D 的大小为 2。为什么在这种情况下行为不同 假设没有从class B和C继承到D的数据成员或虚拟指针?
#include<iostream>
using namespace std;
class A {};
class B : public A {};
class C : public A {};
class D : public B, public C {};
int main() {
cout<<"Size of D is: "<<sizeof(D)<<endl;
return 0;
}
对我来说,空碱基优化是否可以应用在这里,取决于人们如何解释 [intro.object/8]:
Unless an object is a bit-field or a base class subobject of zero size, the address of that object is the address of the first byte it occupies. Two objects a and b with overlapping lifetimes that are not bit-fields may have the same address if one is nested within the other, or if at least one is a base class subobject of zero size and they are of different types; otherwise, they have distinct addresses.
B
和C
是不同的类型吗?他们都是A
。实际上是两个不同的 A
对象。编译器编写者可以在此处停止分别为 B
和 C
分配存储空间,而无需检查 A
是否为空。
值得注意的是,如果您有 B
和 C
继承自 separate 基础,则使用 g++ 时大小会返回 1:
#include<iostream>
class A {};
class A1 {};
class B : public A {};
class C : public A1 {};
class D : public B, public C {};
int main() {
std::cout << "Size of D is: " << sizeof(D) << std::endl;
return 0;
}
这是因为您继承自两个基 class,它们本身派生自相同的基 class A
,看看当您更改程序时输出如何变化对此
#include<iostream>
using namespace std;
class A {};
class Z {};
class B : public A {};
class C : public Z {};
class D : public B, public C {};
int main() {
cout<<"Size of D is: "<<sizeof(D)<<endl;
return 0;
}
如您所见,D
的大小为 1
该问题与您可能知道的可怕钻石的问题类似。编译器试图消除示例中 D
中 A
的两个实例的歧义。并且这里没有应用空基优化,标准没有要求,编译器也没有实现(见下文)
该标准明确允许编译器不对多继承情况应用空基优化。相关引用自标准 here
Allowing standard-layout classes to have base classes forces compilers to implement the empty base optimization for standard-layout classes, and this could break a compiler's application binary interface (ABI). See 9.2/18 above. This is believed not to be a concern for modern compilers, except possibly in the case of multiple inheritance. Since multiple inheritance is not central to this proposal, allowing standard-layout classes or their bases to use multiple inheritance will be eliminated from the proposal if it proves contentious.