Вдохновленный этим cppcon talk by Richard Powell я создал следующий фрагмент кода пошалить:Почему классы с виртуальными функциями выровнены иначе, чем классы без?
#include <iostream>
using std::cout;
using std::endl;
struct erdos
{
void who()
{
cout << "erdos" << endl;
}
float f1;
float f2;
};
struct fermat : public erdos
{
float f3;
};
struct fermat2 : public fermat
{
float f4;
};
struct fermat3 : public fermat2
{
float f5;
};
int main(void)
{
erdos e;
cout << "sizeof(e)" << sizeof(e) << endl;
fermat f;
cout << "sizeof(f)" << sizeof(f) << endl;
fermat2 f2;
cout << "sizeof(f2)" << sizeof(f2) << endl;
fermat3 f3;
cout << "sizeof(f3)" << sizeof(f3) << endl;
cout << "sizeof(void*)" << sizeof(void*) << endl;
cout << "sizeof(float)" << sizeof(float) << endl;
return 0;
}
, который будет печатать:
sizeof(e)8
sizeof(f)12
sizeof(f2)16
sizeof(f3)20
sizeof(void*)8
sizeof(float)4
После добавления virtual
к who()
я получаю эту
sizeof(e)16
sizeof(f)24
sizeof(f2)24
sizeof(f3)32
sizeof(void*)8
sizeof(float)4
Теперь, добавив размер void*
в структуру, просто, но почему будет ли это дополнение (о чем также упоминается Ричардом в его разговоре) в виртуальном случае, а не в не виртуальном случае?
sizeof(e)16 - 8 = 8
sizeof(f)24 - 8 = 16 but is in fact 12 (padding 4)
sizeof(f2)24 - 8 = 16 matches
sizeof(f3)32 - 8 = 24 but is in fact 20 (padding 4)
Я проверил его с GCC 5.3.0 и лязгом 3.7.1 на Ubuntu 14.04 64 битного
Как вы _know_ это дополнение? Возможно, это дополнительные данные, такие как смещения и указатели на таблицы. Это деталь реализации и не гарантируется, что она будет одинаковой для всех компиляторов. –
Вы добавили таблицу виртуальных методов, которая раньше не существовала. – Donnie