2012-06-05 2 views
0

у меня есть «база» класса с виртуальным деструктором и, таким образом виртуальные таблицы и соответствующую РВПТ в нем, и класс, производный от него:Существования VPTR в подобъектах

class base { 
public: 
    virtual ~base() {} 
}; 

class der : base {}; 

main() 
{ 

    int a = sizeof(base); // = 4 , fine ! 

    int b = sizeof(der); // = 4 too ? 
} 

Теперь, как производный класс тоже является виртуальным , у него будет собственный VPTR, но поскольку он также имеет подобъект базового класса с VPTR в нем, не должен быть размером класса 'der' равным 8 байтам, то есть размером VPTR class 'der' + размер VPTR подобъекта класса 'base'? (когда sizeof (void *) = 4 байта).

Так что в основном мой вопрос: когда подобъект класса 'base' сделан в 'der', имеет ли он отдельный новый VPTR? И если это так, то почему его размер не добавляется при расчете размера 'der'?

Может кто-нибудь прояснить это.

+0

Дублирование vptr в производных классах полностью уничтожит цель vptrs: при манипулировании экземпляром 'der' с указателем' base', как бы реализация могла знать, что предполагается получить vptr в производной части объект? Тем не менее, интересно отметить, что объект может иметь несколько vptrs, если он наследует от нескольких полиморфных базовых классов: 'struct A {virtual ~ A() {}}; struct B {virtual ~ B() {}}; struct C: A, B {}; '. В некоторых (наиболее?) Реализациях C будет иметь два vptrs, один в подобъекте 'A' и один в подобъекте' B'. –

+1

, структура struct C выше, несомненно, будет иметь два VPTR, но не должны эти VPTR быть в самом классе C, а не находиться в подобъектах (как указано u), потому что это было не так, тогда как реализация могла знать, что предполагается для получения vptr в производной части объекта? – cirronimbo

ответ

4

Это все, что касается реализации. Но на практике в производном классе будет только один vptr; нет необходимости в двух. Вся точка vptr - это то, что используется для динамического вызова правильного переопределения виртуальной функции; Объекты der просто будут иметь другое значение указателя до base объектов.

[Примечание: Ваш пример, вероятно, смущает тот факт, что вы используете личное наследство, а не более типичного общественного наследования ... (неумышленно?)]

+0

Я не использовал публичное наследование, потому что (насколько я знаю) это не имело никакого отношения к тому, что я прошу. И, извините, я не смог получить ваш ответ. Что я спрашивал о VPTR в под-объекте «базы». – cirronimbo

+0

cirronimmplo: Он говорит, что производный класс не нуждается в виртуальном ptr для базового класса, и поэтому vptr для производного класса перезаписывает его. –

+0

@cirronimbo: Если у вас есть объект 'base', то vptr указывает на таблицу vtable для' base'. Если у вас есть объект 'der', то vptr указывает на vtable для' der'. –

2

Я думаю, ты путаешь виртуальные таблицы и vptrs. Каждый класс будет иметь vtable, и каждый объект будет хранить указатель на свой vtable в качестве vptr. Vtable похож на статический глобальный, он разделяется между всеми экземплярами класса и, следовательно, не занимает места в объекте.

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