C++ 中带有 int 、函数、虚函数的 sizeof 类?

2021-12-09 00:00:00 class object c++ virtual sizeof

这是一道在线C++试题,已经做完了.

This is an online C++ test question, which has been done.

#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; 
}

输出:

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

我的问题:

为什么 siszeof(A) 是 1 而 sizeof(C) 也是 1?

Why siszeof(A) is 1 and sizeof(C) is 1 too ?

为什么 siszeof(H) 是 16 而 sizeof(G) 是 4 ?

Why siszeof(H) is 16 but sizeof(G) is 4 ?

为什么 siszeof(E) 是 16 而 sizeof(F) 是 4 ?

Why siszeof(E) is 16 but sizeof(F) is 4 ?

为什么 siszeof(D) 是 8 而 sizeof(E) 是 16 ?

Why siszeof(D) is 8 but sizeof(E) is 16 ?

我的猜测:

虚函数是一个8字节的指针.但是,我不知道为什么 E 大小是 16 ?向空类添加函数不会改变其大小?

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 字节的指针.在 C++ 中,只有 sizeof(char) 保证是任意数量的字节.

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.

第二,只有类中的第一个虚函数会增加其大小(依赖于编译器,但在大多数情况下 - 如果不是全部 - 就像这样).所有后续方法都没有.非虚函数不影响类的大小.

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.

如果你有:

class A
{
   virtual void foo();
}

class B
{
   virtual void goo();
   virtual void test();
   static void m();
   void x();
}

你会有 sizeof(A) == sizeof(B).

现在:

为什么 siszeof(A) 是 1 而 sizeof(C) 也是 1?

Why siszeof(A) is 1 and sizeof(C) is 1 too ?

AC 的大小为 1 只是因为不允许类的大小为 0.函数与它无关.这只是一个虚拟字节.

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.

为什么 siszeof(H) 是 16 而 sizeof(G) 是 4 ?

Why siszeof(H) is 16 but sizeof(G) is 4 ?

G 只有一个成员占内存 - int.在你的平台上,sizeof(int) == 4.H,除了int,还有一个指向vftable(虚函数表,见上)的指针.this 的大小、int 的大小和对齐方式是特定于编译器的.

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.

为什么 siszeof(E) 是 16 而 sizeof(F) 是 4 ?

Why siszeof(E) is 16 but sizeof(F) is 4 ?

上面解释了 - 非虚方法不占用类中的内存.

Explained above - non virtual methods don't take up memory in the class.

为什么 siszeof(D) 是 8 而 sizeof(E) 是 16 ?

Why siszeof(D) is 8 but sizeof(E) is 16 ?

D 仅包含 vftable 指针,它在您的平台上显然是 8 个字节.E 也有一个 int,vftable 对齐到 8 个字节.所以它是这样的:

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:

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 |

相关文章