размер класса в виртуальном наследовании
Размер классов, как следует при использовании виртуального наследования..
ABase=4(sizeof imem)
BBase=12(sizeof imem+ABase+VBase_ptr)
CBase=12(sizeof imem+ABase+VBase_ptr)
Это оправдано, но я не понимаю, почему размер ABCDerived равен 24.
class ABase{
int iMem;
};
class BBase : public virtual ABase {
int iMem;
};
class CBase : public virtual ABase {
int iMem;
};
class ABCDerived : public BBase, public CBase {
int iMem;
};
2 ответа:
Это будет крайне зависимо от платформы, но я думаю, что мы можем понять, что происходит.
Во-первых, стандарт не определяет, как должна быть реализована виртуальная inheitence. Что касается стандарта, то нет даже такой вещи, как vtable.
ABCDerivedимеетBBaseиCBase, Каждый из которых состоит изint. Существует также единственный экземплярABase, который состоит изint. Наконец, есть vtable ptr.Размер
intзависит от платформы - это не обязательно 4 байта. Но если мы предположим, что это 4 байта, и размер vtable также 4 байта, мы имеем:Однако это не означает, чтоint [ABCDerived] = 4 bytes int [CBase] = 4 bytes int [BBase] = 4 bytes int [ABase] = 4 bytes vtable = 4 bytes ------------- 20 bytessizeof (ABCDerived)равно 20. Выравнивание приходит, чтобы играть здесь, а также. Стандарт позволяет компиляторам увеличивать размер объекта таким образом, чтобы он делился на несколько целых слов.Рассмотрим:
class ABase{ int iMem; }; class BBase : public virtual ABase { int iMem; }; class CBase : public virtual ABase { int iMem; }; class ABCDerived : public BBase, public CBase { int iMem; }; int main() { ABCDerived d; BBase& b = d; ABase* ab = &b; CBase& c = d; ABase* ac = &b; cout << hex << (void*) ab << "\n" << hex << (void*) ac << "\n"; cout << sizeof (d) << "\n" << sizeof (int) << "\n"; }Вывод
28на моей 64-битной машине Linux.Однако, если я повернусь при упаковке (с использованием зависящего от платформы переключателя #pragma):
#pragma pack (1)Выход теперь равен 20.
Итак, длинное и короткое из всего этого:Здесь происходит тонна зависящих от платформы вещей. Вы не можете сказать, что размер объекта тот или иной, по крайней мере, без использования более зависимых от платформы вещей и знания того, как ваш компилятор фактически реализует виртуальное наследование. Размер его-это то, что он есть.