gpt4 book ai didi

c++ - 具有虚函数的类的大小 GCC/Xcode

转载 作者:行者123 更新时间:2023-11-30 03:06:11 25 4
gpt4 key购买 nike

谁能给我解释一下这是怎么回事?首先,我认为大多数程序员都知道带有虚函数的类有一个 vtbl,因此在它的顶部有 4 个额外的字节。据我所知,这是相当标准的。我已经对此进行了测试并利用了这一事实,然后从带有修补的 vtbls 的二进制文件中就地加载。在过去的 6 个月里,我一直在使用 Xcode,最近才遇到需要做一些就地加载的事情,所以我再次考虑修补 vtbls。为了确保我的理解是正确的,我写了一个示例程序。在这里:

class A
{
public:
virtual int getData()
{
return a;
}

virtual void print()
{
printf("hello\n");
}
int a;
};

class B : public A
{
public:
int getData()
{
return b;
}
int b;
};

class C : public B
{
public:
int getData()
{
return c;
}

void print()
{
printf("world\n");
}
int c;
};

class D
{
public:
int a;
int b;
};

int main (int argc, const char * argv[])
{
A* tA = new A();
tA->a = 1;

printf("A: %d\n", sizeof(A));
printf("A data: %d\n", tA->getData());

B* tB = new B();
tB->a = 2;
tB->b = 4;

printf("B: %d\n", sizeof(B));
printf("B data: %d\n", tB->getData());

C* tC = new C();
tC->c = 8;

printf("C: %d\n", sizeof(C));
printf("C data: %d\n", tC->getData());

A* aC = tC;
aC->print();

printf("D: %d\n", sizeof(D));

return 0;
}

我的预期输出是:

答:8

A数据:1

乙:12

B数据:4

中:16

C数据:8

世界

直径:8

但是,我得到的输出是:

答:16

A数据:1

乙:16

B数据:4

C:24

C数据:8

世界

直径:8

有人知道这里发生了什么吗?谢谢!

最佳答案

A 到 C 类的实例包含一个 vptr,一个指向动态类型的虚函数表的指针。该指针在您的 64 位机器上占用 8 个字节(或在 32 位机器上占用 4 个字节)。每个 int 成员占用 4 个字节。

sizeof(Class) 的最小值是所有成员的 sizeof(member) 之和。如果是这样的话,那么

sizeof(A) = 8 (vptr) + 4 (int a) = 12
sizeof(B) = 8 (vptr) + 4 (int a) + 4 (int b) = 16
sizeof(C) = 8 (vptr) + 4 (int a) + 4 (int b) + 4 (int c) = 20
sizeof(D) = 4 (int a) + 4 (int b) = 8

但是,这只是最小 尺寸。编译器通常会将这个大小增加到 sizeof(void*) 的倍数,这里是 8 个字节。此过程称为对齐。看起来这可能会浪费内存,但性能提升可以抵消这一点:CPU 可以比读取非对齐数据更快地读取对齐数据。

顺便说一下,如果您使用的是 32 位计算机,您的预期结果应该是正确的。指针(尤其是 vptr)在那里有 4 个字节宽,并且对齐也是 4 个字节的倍数。由于相关类的所有数据成员都是 4 字节大,因此对齐不会在那里做任何事情。

关于c++ - 具有虚函数的类的大小 GCC/Xcode,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6875783/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com