2013-08-10 10 views
3

1.Что такое размер класса Derived4 показывает 8 байтов?Размер пустого класса и производного виртуального класса

class Empty 
{}; 
class Derived4 : virtual public Empty 
{ 
    char c; 
}; 

2. В то время как размер класса Derived2 показывает 4 байта ??

class Empty 
{}; 
class Derived2 : virtual public Empty 
{}; 
+0

Заполнение границы слова? Что произойдет, если вы добавите поля 'char'? – millimoose

+0

Это реализация определена и, следовательно, довольно трудно ответить, но зачем вам все равно? – nijansen

+0

это была бы моя ставка.vtable вызывает лишние 4 байта, и смысл «char» составляет всего 1 байт, в итоге вы получаете в общей сложности 5. компилятор, вероятно, делает его 8 байтов, там есть инструкции для работы с 8 байтовыми значениями – Jake

ответ

5

Отметьте, что sizeof(any_class) определяется реализацией.

Но что на самом деле происходит в вашем случае. Ну, он использует virtual наследование, большинство реализаций используют скрытый указатель для реализации этой функции, которые стоят sizeof(pointer) байт (указатель хранится в самом производном классе), плюс SizeOf все члены (если таковые имеются), плюс padding при необходимости, plus sizeof базового класса (который может быть сведен к нулю, в случае пустого базового класса, из-за оптимизации с пустым основанием).

Для получения более подробного ответа найдите "padding in C++" на этом сайте. На нем вы найдете множество тем.

+0

Имеет ли Vptr & Vtable изображение на графике даже в случае виртуального наследования, я думал, что оно появляется на картинке Только тогда, когда у вас есть виртуальные Fuunctions в вашем классе bcz, когда вам понадобится Vtable .., уточните – GeekPanther

+0

@GeekPanther: Да. Один 'vptr' для одной виртуальной базы. Поэтому, если у вас есть два виртуальных базовых класса, будет два 'vptr', и размер класса будет вычисляться соответствующим образом. В случае пустых базовых классов компилятор может оптимизировать это, поэтому вместо двух он может иметь только один. – Nawaz

+0

Тогда в этом случае будет содержимое Vtable, так как в случае Vfunction он содержит адрес Vfunctions, что будет содержать Vtable в случае Virtual Inheritence (без каких-либо VFunc)? – GeekPanther

2

Почему размер Derived4 класс показывает 8 байтов?

class Empty 
{}; 
class Derived4 : virtual public Empty 
{ 
    char c; 
}; 

Под 32-битной машине G ++ генерирует 1 байт для пустого класса (Симметричного для представления имени класса в памяти). Это предполагаемое поведение.

Вы наследуя Empty в Derived4 в virtual public с результатом в создании __vptr переменной в классе Derived4 компилятором по умолчанию. Таким образом, класс Derived4 будет выглядеть примерно так,

class Derived4 { 
    void* __vptr; // 4 bytes 
    char c; // 4 bytes as 1 char + 3 for structure padding 
}; 

поэтому размер указанного класса в 8 байт, я надеюсь, что вы с этим согласны.


В то время как размер Derived2 класса показывает 4 байта?

class Empty 
{}; 
class Derived2 : virtual public Empty 
{}; 

Здесь же принцип применит и для пустого класса 1 байта и наследования в EmptyDerived4 в качестве виртуальных результатов __vptr переменного, вставленных в Derived4 классе. Таким образом, размер Dervied4: sizeof(void*); который представляет собой не что иное, как размер 4 байта в 32-битной машине.

+0

Четко объяснено. – Snehasish

2

Я бы добавил к утверждениям Saravanan, что это правда, что пустые классы имеют размер не 0 байтов, но при использовании в качестве базового класса, тогда благодаря EBCO (Empty Base Class Optimization) базовый класс «накладные расходы» удаляется.

Смежные вопросы