C++ 中带有 int 、函数、虚函数的 sizeof 类?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9439240/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
sizeof class with int , function, virtual function in C++?
提问by user1002288
This is an online C++ test question, which has been done.
这是一道在线C++测试题,已经做完了。
#include<iostream>
using namespace std;
class A
{
};
class B
{
int i;
};
class C
{
void foo();
};
class D
{
virtual void foo();
};
class E
{
int i ;
virtual void foo();
};
class F
{
int i;
void foo();
};
class G
{
void foo();
int i;
void foo1();
};
class H
{
int i ;
virtual void foo();
virtual void foo1();
};
int main()
{
cout <<"sizeof(class A) : " << sizeof(A) << endl ;
cout <<"sizeof(class B) adding the member int i : " << sizeof(B) << endl ;
cout <<"sizeof(class C) adding the member void foo() : " << sizeof(C) << endl ;
cout <<"sizeof(class D) after making foo virtual : " << sizeof(D) << endl ;
cout <<"sizeof(class E) after adding foo virtual , int : " << sizeof(E) << endl ;
cout <<"sizeof(class F) after adding foo , int : " << sizeof(F) << endl ;
cout <<"sizeof(class G) after adding foo , int : " << sizeof(G) << endl ;
G g;
cout <<"sizeof(class G) after adding foo , int : " << sizeof(g) << endl ;
cout <<"sizeof(class H) after adding int 2 virtual " << sizeof(H) << endl ;
return 0;
}
output:
输出:
sizeof(class A) : 1
sizeof(class B) adding the member int i : 4
sizeof(class C) adding the member void foo() : 1
sizeof(class D) after making foo virtual : 8
sizeof(class E) after adding foo virtual , int : 16
sizeof(class F) after adding foo , int : 4
sizeof(class G) after adding foo , unsigned int : 4
sizeof(class g) after adding foo , unsigned int : 4
sizeof(class H) after adding int 2 virtual 16
My questions:
我的问题:
Why siszeof(A)
is 1 and sizeof(C)
is 1 too ?
为什么siszeof(A)
是 1 并且sizeof(C)
也是 1 ?
Why siszeof(H)
is 16 but sizeof(G)
is 4 ?
为什么siszeof(H)
是 16 而是sizeof(G)
4 ?
Why siszeof(E)
is 16 but sizeof(F)
is 4 ?
为什么siszeof(E)
是 16 而是sizeof(F)
4 ?
Why siszeof(D)
is 8 but sizeof(E)
is 16 ?
为什么siszeof(D)
是 8 而是sizeof(E)
16 ?
My guess:
我猜:
A virtual function is a pointer with 8 bytes.
But, I do not know why E
size is 16 ?
Adding a function to an empty class does not change its size ?
虚函数是一个 8 字节的指针。但是,我不知道为什么E
size 是 16 ?向空类添加函数不会改变其大小?
Any help is appreciated.
任何帮助表示赞赏。
thanks
谢谢
回答by Luchian Grigore
First off, a virtual function is not a pointer with 8 bytes. In C++ nothing but sizeof(char)
is guaranteed to be any number of bytes.
首先,虚函数不是一个有 8 个字节的指针。在 C++ 中,什么都没有,但sizeof(char)
保证是任意数量的字节。
Second, only the first virtual function in a class increases its size (compiler-dependent, but on most - if not all - it's like this). All subsequent methods do not. Non-virtual functions do not affect the class's size.
其次,只有类中的第一个虚函数会增加其大小(依赖于编译器,但在大多数情况下 - 如果不是全部 - 就像这样)。所有后续方法都没有。非虚函数不影响类的大小。
This happens because a class instance doesn't hold pointers to methods themselves, but to a virtual function table, which is one per class.
发生这种情况是因为类实例不保存指向方法本身的指针,而是指向一个虚函数表,每个类一个。
So if you had:
所以如果你有:
class A
{
virtual void foo();
}
and
和
class B
{
virtual void goo();
virtual void test();
static void m();
void x();
}
you would have sizeof(A) == sizeof(B)
.
你会的sizeof(A) == sizeof(B)
。
And now:
现在:
Why siszeof(A) is 1 and sizeof(C) is 1 too ?
为什么 siszeof(A) 是 1 而 sizeof(C) 也是 1 ?
A
and C
have size 1 just because it's not allowed for a class to be of size 0. The functions have nothing to do with it. It's just a dummy byte.
A
并且C
大小为 1 只是因为不允许类的大小为 0。函数与它无关。这只是一个虚拟字节。
Why siszeof(H) is 16 but sizeof(G) is 4 ?
为什么 siszeof(H) 是 16 而 sizeof(G) 是 4 ?
G
has only one member that accounts for memory - the int
. And on your platform, sizeof(int) == 4
. H
, besides the int
, also has a pointer to the vftable
(virtual function table, see above). The size of this, size of int and allignment are compiler specific.
G
只有一个成员占内存 - int
. 在您的平台上,sizeof(int) == 4
. H
, 除了int
, 还有一个指向vftable
(虚函数表,见上)的指针。this 的大小、int 的大小和 allignment 是编译器特定的。
Why siszeof(E) is 16 but sizeof(F) is 4 ?
为什么 siszeof(E) 是 16 而 sizeof(F) 是 4 ?
Explained above - non virtual methods don't take up memory in the class.
上面解释了 - 非虚拟方法不占用类中的内存。
Why siszeof(D) is 8 but sizeof(E) is 16 ?
为什么 siszeof(D) 是 8 而 sizeof(E) 是 16 ?
D
only contains the vftable
pointer which is apparently 8 bytes on your platform. E
also has an int, and the vftable
is aligned to 8 bytes. So it's something like:
D
仅包含vftable
在您的平台上显然为 8 个字节的指针。E
也有一个 int,并且vftable
对齐到 8 个字节。所以它是这样的:
class E
4 bytes for int | 4 padding bytes | 8 bytes for vftable pointer |
| x | x | x | x | | | | | v | v | v | v | v | v | v | v |
回答by je4d
Why siszeof(A) is 1 and sizeof(C) is 1 too ?
为什么 siszeof(A) 是 1 而 sizeof(C) 也是 1 ?
The function in C
is not virtual, so the class doesn't need a vtable pointer, so it needs no more storage than A
. Neither A
nor C
need any storage at all, but because language requires that different instances of the same class have different pointers, they can't have a size of zero - so the compiler makes them as small as it can, i.e. 1 byte.
in 函数C
不是虚拟的,所以这个类不需要 vtable 指针,所以它不需要比A
. 既不需要A
也不C
需要任何存储,但是由于语言要求同一类的不同实例具有不同的指针,因此它们的大小不能为零 - 因此编译器使它们尽可能小,即 1 个字节。
Why siszeof(H) is 16 but sizeof(G) is 4 ?
为什么 siszeof(H) 是 16 而 sizeof(G) 是 4 ?
G
has no virtual functions, so all it needs to store is the int, which on your compiler and architecture is 4 bytes.
G
没有虚函数,所以它需要存储的只是 int,它在你的编译器和架构上是 4 个字节。
H
has virtual functions, so the class needs to contain an int
and a vtable pointer. All widely used compilers store the vtable pointer at the start of the class, so the layout is {vptr, int}, which is 8+4=12 bytes if you're on a 64 bit host.
H
具有虚函数,因此该类需要包含一个int
和一个 vtable 指针。所有广泛使用的编译器都在类的开头存储 vtable 指针,因此布局为 {vptr, int},如果您在 64 位主机上,则为 8+4=12 字节。
However, the compiler is free to pad this out to 16 bytes so that if multiple instances of H
are allocated in an array then all of them will be word-aligned. This is important because there are significant performance implications for accessing a pointer (i.e. the vtable pointer here) if it is not word-aligned.
但是,编译器可以自由地将其填充到 16 个字节,这样如果H
在一个数组中分配了多个实例,那么所有实例都将是字对齐的。这很重要,因为如果指针不是字对齐的,那么访问指针(即此处的 vtable 指针)会对性能产生重大影响。
Why siszeof(E) is 16 but sizeof(F) is 4 ?
为什么 siszeof(E) 是 16 而 sizeof(F) 是 4 ?
E has virtual functions, so needs a vtable ptr, so its layout is just like H
's. F
has no virtual functions, it only has an int, so its layout is just like G
's. so the answer's the same as for G
and H
.
E 有虚函数,所以需要一个 vtable ptr,所以它的布局就像H
's. F
没有虚函数,只有一个int,所以它的布局就像G
's. 所以答案与 forG
和相同H
。
The ordering of the members/functions just doesn't matter here because there's only one member variable and the vtable ptr always goes first if there is one.
成员/函数的顺序在这里并不重要,因为只有一个成员变量,如果有一个,vtable ptr 总是排在第一位。
Why siszeof(D) is 8 but sizeof(E) is 16 ?
为什么 siszeof(D) 是 8 而 sizeof(E) 是 16 ?
D
has no member variables, but it has a virtual function, so it needs a vtable pointer. The vtable pointer is the only thing it needs, so its size is sizeof(void*)
, which is 8 bytes. E
needs the same as D
, plus 4 bytes for an integer, and the compiler rounds it up to 16 bytes for alignment.
D
没有成员变量,但是有虚函数,所以需要一个vtable指针。vtable 指针是它唯一需要的东西,所以它的大小是sizeof(void*)
,也就是 8 个字节。E
需要与 , 相同D
的整数加上 4 个字节,编译器将其四舍五入为 16 个字节以进行对齐。
回答by CygnusX1
- sizeof(A)==1
- 大小(A)==1
It is so because of C++ standard which prohibits classes/structs of size 0. That's why an empty struct/class have size 1. I find it pretty annoying, but they had some reasoning for that.
这是因为 C++ 标准禁止大小为 0 的类/结构。这就是为什么空结构/类的大小为 1。我觉得这很烦人,但他们对此有一些推理。
- sizeof(B)==4
- 大小(B)==4
That's the size of int, plain and simple :)
这就是 int 的大小,简单明了:)
- sizeof(C)==1
- 大小(C)==1
That's the size of an empty struct (see A). Nonvirtual functions do not contribute to the object size at all. There is nothing you need to store in an object to be able to call its nonvirtual member function.
这是一个空结构体的大小(见 A)。非虚拟函数根本不会影响对象大小。您无需在对象中存储任何内容即可调用其非虚拟成员函数。
- sizeof(D)==8
- 大小(D)==8
I am assuming that you are building a 64-bit application. Any class having at least 1 virtual function has a pointer to a virtual method table. This allows you to call a correct virtual function even if an object pointer was casted to some parent class. Often the pointer is referred to as a vtable. More reading at wiki: http://en.wikipedia.org/wiki/Virtual_method_table
我假设您正在构建一个 64 位应用程序。任何具有至少 1 个虚函数的类都有一个指向虚方法表的指针。即使对象指针被强制转换为某个父类,这也允许您调用正确的虚函数。通常指针被称为vtable。更多 wiki 阅读:http: //en.wikipedia.org/wiki/Virtual_method_table
I think the size 8 is coming from that 64-bit pointer.
我认为大小 8 来自该 64 位指针。
- sizeof(E)==16
- 大小(E)==16
To store a pointer and an int you technically need 12 bytes. However, a pointer must be aligned to 8 bytes. Now envision yourself creating an array A of objects E. A[0].vtable
would have address &A+0, A[0].i
would be at &A+8
, A[1].vtable
would be at &A+12
-- woops, we have a problem, 12 is not divisable by 8. That's why compiler creates a padding. It adds additional useless bytes to make the object align correctly in an array. In this case, the lowest divisable by 8 number is 16. Hence the size.
要存储一个指针和一个 int,技术上需要 12 个字节。但是,指针必须对齐到 8 个字节。现在设想自己创建一个对象 E 的数组 A。A[0].vtable
将具有地址 &A+0,A[0].i
将在&A+8
,A[1].vtable
将在&A+12
-- woops,我们有一个问题,12 不能被 8 整除。这就是编译器创建padding的原因。它添加了额外的无用字节以使对象在数组中正确对齐。在这种情况下,可被 8 整除的最小数是 16。因此大小。
- sizeof(F)==4
- 大小(F)==4
Same as in case of C - nonvirtual functions do not contribute at all to the size, so your size matches B.
与 C 的情况相同 - 非虚拟函数对大小根本没有贡献,因此您的大小与 B 匹配。
sizeof(G)==4 -- same as F
sizeof(H)==16
sizeof(G)==4 -- 与 F 相同
大小(H)==16
The number of virtual functions does not matter. There is still only one vtable pointer in your object. If you put more virtual functions, the virtual table gets larger, but not the object itself. In many object-oriented programs you often end up with lots of virtual functions. Having pointers stored directly in the object itself would be wasteful.
虚函数的数量无关紧要。您的对象中仍然只有一个 vtable 指针。如果你放更多的虚函数,虚表会变大,但对象本身不会变大。在许多面向对象的程序中,您经常会得到许多虚函数。将指针直接存储在对象本身中会很浪费。
That's why the size (and the explanation) of H matches the size of E.
这就是为什么 H 的大小(和解释)与 E 的大小相匹配的原因。
回答by CygnusX1
Size of int with padding and the virtual function =18 bytes
带填充和虚函数的 int 大小 =18 字节
simple function bytes =1 virtual function =8
简单函数字节 =1 虚函数 =8
And you cant simply add all the bytes there is concept of padding check it out on google.
而且您不能简单地添加所有字节,有填充的概念,请在谷歌上查看。
Declaring in different order change the size of class
以不同的顺序声明改变类的大小