班级规模 - C++
我有以下关于对象大小的代码:
class A
{
public:
int _i;
virtual int getI () = 0;
int setI (int i);
};
class B : public A
{
public:
int getI ();
virtual int setI (int i);
};
class C : public B
{
public:
int _i;
int getI ();
int setI (int i);
};
int main ()
{
B b;
C c;
}
Why the size of Cc; 是12?尺寸计算中包括哪些部分?
I have the following code about object sizes:
class A
{
public:
int _i;
virtual int getI () = 0;
int setI (int i);
};
class B : public A
{
public:
int getI ();
virtual int setI (int i);
};
class C : public B
{
public:
int _i;
int getI ();
int setI (int i);
};
int main ()
{
B b;
C c;
}
Why the size of
C c;
is 12? What parts included in the size calculation?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
sizeof(int A::_i) + sizeof(int C::_i) + sizeof(pointer to virtual table)
所有这些部分的大小取决于实现,在您的情况下,每个部分都有尺寸 4。
sizeof(int A::_i) + sizeof(int C::_i) + sizeof(pointer to virtual table)
The size of all these parts is implementation-dependent, in your case, each one has size 4.
几乎任何类的大小都取决于实现,但我会
猜测你在 32 位机器上,并且 C 类包含 4 个字节
vptr
和两个四字节int
(A::_i
和C::_i
)。The size of just about any class is implementation dependent, but I'll
guess that you're on a 32 bit machine, and class C contains a 4 byte
vptr
and two four byteint
(A::_i
andC::_i
).对象的大小将是特定于平台的。例如,在 64 位平台上,我希望大小为 24 字节。物体的大小由什么构成有点棘手。它由各种组件组成:
int
,即这将贡献2 * sizeof( int)
。大多数隐藏的内容并不适用,但对于您的类,您有
2 * sizeof(int) + sizeof(T*)
用于访问虚拟函数表的合适类型。The size of the object will be platform specific. For example on a 64 bit platform I would expect the size to be 24 bytes. What constitutes the size of an object is a bit tricky. It is made up from variety of components:
int
somewhere in the hierarchy, i.e. this will contribute2 * sizeof(int)
.Most of the hidden stuff doesn't apply but for you class you have
2 * sizeof(int) + sizeof(T*)
for a suitable type used to access the virtual function table.C c;
的大小实际上是实现定义的。如果您有任何实际依赖于大小的代码,则该代码是严重错误的,并且在切换编译器时可能会中断。现在回答您的实际问题:您可能认为
C
具有C
中包含的int
的大小,或者您可能认为它具有来自C
的int
的大小加上来自A
的大小。这两种猜测都是错误的,原因有两个:
您的结构中可能存在所谓的填充。有时类型需要与某些边界对齐。为了强制这些对齐,编译器在字段之间引入了一些“浪费”的空间区域,以将它们保留在这些位置。您永远不能依赖此填充的数量。
还有一点,我主要认为你的老师想向你展示这一点:如果你编写
c.getI()
,计算机必须知道要调用哪个方法,即是否调用来自A
、B
或C
之一。这些信息需要存储在某个地方。此信息的存储会为您的结构添加一些额外的大小,但您永远不能依赖会添加多少。有些人可能会试图告诉您这只是使用一个指针来存储的,但这是不正确的。编译器可以使用尽可能多的空间来存储这些信息。大多数编译器出于效率原因只使用一个指针,但如果您依赖这一点,对于以不同方式处理此问题的编译器来说,您的代码将会是错误的。如果您想了解更多信息,只需谷歌搜索“虚拟方法调用”,您就可以找到该用例的常见实现的一些示例。
The size of
C c;
is actually implementation defined. If you have any code that actually relies on the size, this code is horribly wrong and may break whenever the compiler is switched.Now to your actuall questions: You probably either thought
C
would have the size of theint
contained inC
or alternatively you would have thought it to have the size of theint
fromC
plus the one fromA
.Both these guesses are wrong for two reasons:
There might be so called padding in your structures. Sometimes types need to be aligned to certain boundaries. In order to enforce these alignments, the compiler introduces some area of "wasted" space between your fields to keep them at these places. You can never rely on the amount of this padding.
There is another point, and I mainly think your teacher wanted to show you this: If you write
c.getI()
the computer has to know which method to call, i.e. whether to call the one fromA
,B
orC
. This information needs to be stored somewhere. The storage for this information adds some additional size to your struct, but you can never rely on how much will be added. Some people might try to tell you that this is only stored by using one pointer, but this is not correct. The compiler is allowed to use as much space to store this information as it likes. Most compiler only do use one pointer for efficiency reasons, but if you rely on this, your code will be wrong for compilers which do handle this differently.If you want to know more, just google for "virtual method invocation", and you can find some examples for common implementations for this use-case.
我认为你使用 32 位编译器。
这是C类的内存布局:
根据它,你可以看到哪些部分影响类的大小。
您可以阅读有关虚拟函数、虚拟继承、虚拟表的更多信息,以了解它们的组织方式以及对类大小的影响。
如果您使用 MVSC,则可以在编译时使用 -d1reportAllClassLayout 选项来查看类的布局。
I think you use 32 bit compiler.
This is the memory layout of class C:
Based on it, you can see which parts conduct to size of class.
You can read more about virtual function, virtual inheritance, virtual table to figure out the way that they are organized and contributed to class size.
If you use MVSC, you can use -d1reportAllClassLayout option when you compile to see the layout of your class.