Learning¶
内存¶
空类的内存占用¶
Note
对于一个什么数据都没有存的类。声明他会占用多少内存
在C++中,即使一个类什么数据成员都没有,对象实例也会占用内存。这是因为每个对象必须有唯一地址,以便区分不同实例。
没有虚函数时:空类对象通常占用1字节(用于区分不同对象)。 有虚函数时:对象会多一个虚表指针(vptr),通常占用4字节(32位系统)或8字节(64位系统)。 示例:
总结: 空类对象至少占用1字节,有虚函数则占用虚表指针大小。
区分不同对象什么意思
“区分不同对象”指的是:即使类没有成员变量,编译器也要保证每个对象实例在内存中有唯一的地址。这样你可以创建多个该类的对象,并且它们的地址不同,可以通过指针或引用区分它们。
例如:
如果对象大小为0,两个对象可能会有相同的地址,这会导致程序无法正确区分它们。因此,C++标准规定空类对象至少占用1字节。
虚函数的具体存储和实现¶
Code
Anly
- Child child; 在栈上分配一个Child对象。 内存布局(假设无填充): vptr(虚函数表指针) int a(来自Base) int b(来自Child)
- Base* bPtr = dynamic_cast
(&child); bPtr指向child对象的Base部分。 实际上,bPtr和&child指向同一块内存,只是类型不同。 - Base arr = new Base[5]; 在堆上分配一个指针数组,能存放5个Base。
- arr[0] = bPtr; arr[0]指向child对象(以Base*类型)。
- arr[1] = new Base(); 在堆上分配一个Base对象,arr[1]指向它。
- for (int i = 0; i < 2; ++i) { arr[i]->Work(); } arr[0]->Work();:指向child对象,类型为Base*,但由于Work是虚函数,会动态绑定到Child::Work()。 arr[1]->Work();:指向Base对象,调用Base::Work()。
- bPtr->Work(); 同样指向child对象,类型为Base*,调用Child::Work()。