类方法会增加类实例的大小吗?
这个问题很直接.为清楚起见,请考虑以下示例:
The question is pretty straight forward. For clarity, consider the example below:
// Note that none of the class have any data members
// Or if they do have data members, they're of equal size, type, and quantity
class Foo {
public:
void foo1();
void foo2();
// 96 other methods ...
void foo99();
};
class Bar {
public:
// Only one method
void bar();
};
class Derived1 : public Foo { };
class Derived2 : public Bar { };
int main() {
Foo f;
Bar b;
Derived1 d1;
Derived2 d2;
return 0;
}
实例f
、b
、d1
和d2
都占用相同的内存空间?作为这个问题的扩展,理论上,在传递 Foo
的实例时复制它比 Bar
花费的时间更长吗?
Do instances f
, b
, d1
, and d2
all occupy the same amount of space in memory? As an extension to this question, would copying instances of Foo
when passing it around take longer than Bar
, theoretically?
推荐答案
只有实例数据会增加类的实例的大小(在我所知道的所有实现中),除非添加虚函数或从类继承使用虚函数,那么你会一次性命中 v-table 指针.
Only instance data increases the size of instances of a class (in all implementations that I know of), except that if you add virtual functions or inherit from a class with virtual functions then you take a one-time hit for a v-table pointer.
另外,正如其他人正确提到的,类的最小大小是 1 个字节.
Also, as someone else correctly mentions the minimum size of a class is 1 byte.
一些例子:
// size 1 byte (at least)
class cls1
{
};
// size 1 byte (at least)
class cls2
{
// no hit to the instance size, the function address is used directly by calling code.
int instanceFunc();
};
// sizeof(void*) (at least, for the v-table)
class cls3
{
// These functions are indirectly called via the v-table, a pointer to which must be stored in each instance.
virtual int vFunc1();
// ...
virtual int vFunc99();
};
// sizeof(int) (minimum, but typical)
class cls4
{
int data;
};
// sizeof(void*) for the v-table (typical) since the base class has virtual members.
class cls5 : public cls3
{
};
编译器实现可能会使用多个 v-table 指针或其他方法处理多个虚拟继承,因此这些也会对类大小产生影响.
Compiler implementations may handle multiple virtual inheritance with multiple v-table pointers or other other methods, so these too will have effect on the class size.
最后,成员数据对齐选项会产生影响.编译器可能有一些选项或 #pragma
来指定成员数据的起始地址应该是指定字节数的倍数.例如,对齐 4 字节边界并假设 sizeof(int) = 4
:
Finally, member data alignment options can have an impact. The compiler may have some option or #pragma
to specify that member data should have a starting address that is a multiple of the number of bytes specified. For example, with alignment on 4 byte boundaries and assuming sizeof(int) = 4
:
// 12 bytes since the offset of c must be at least 4 bytes from the offset of b. (assuming sizeof(int) = 4, sizeof(bool) = 1)
class cls6
{
int a;
bool b;
int c;
};
相关文章