2009-07-20 4 views
2

Компиляция следующий классЧто такое «почти пустой» класс?

class Interface 
{ 
    virtual void doIt() = 0; 
    virtual ~Interface() = 0; 
}; 

inline Interface::~Interface() {} 

использованием gcc -fdump-class-hierarchy.

gcc излучает

 
Class Interface 
    size=4 align=4 
    base size=4 base align=4 
Interface (0x1a779c0) 0 nearly-empty 
    vptr=((& Interface::_ZTV9Interface) + 8u) 

Что такое значение "почти пустой"? Что это значит?

+0

Не связано, но .. Не создавайте виртуальный деструктор как чистый виртуальный, как вы обеспечиваете реализацию. – Naveen

+4

Я не думаю, что это особенно хороший совет. Чистые виртуальные деструкторы - это общая сокращенная версия, говорящая, что класс является абстрактным, и они должны иметь реализацию. – 2009-07-20 11:25:09

+1

@Naveen: Почему бы и нет? Любая чистая виртуальная функция может иметь реализацию. – dalle

ответ

4

C++ ABI обеспечивает определение «почти пустые» классы и интересную дискуссию о том, как они влияют на виртуальные таблицы строительства:

Класс, который содержит виртуальный указатель, но никаких других данных, кроме (возможно) виртуальных баз , В частности, это:

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

Я побежал через это во время исследования влияния почти пустых виртуальных баз на размер объекта, размер, виртуальные таблицы и накладные расходы виртуального вызова.

3

Он имеет только таблицу vtable, без полей данных.

6

Я предполагаю, что это должно отличать его от «пустого», что и получается, если вы компилируете класс без каких-либо элементов. «почти пустой», по-видимому, означает, что он имеет vtable и ничего больше.

6

В C++ есть что-то, называемое «пустая оптимизация базы». Если класс не имеет членов, ему не нужно занимать место, когда оно используется как базовый класс. Примером тому, почему это важно, является std::unary_function<T, U>. Он существует, чтобы предоставить вам простой набор typedefs. Эти typedefs не должны вносить вклад в размер вашего класса функторов.

Если у вас есть базовый класс с указателем vtable, этот указатель может быть разделен с производным классом. Вы просто создаете vtable для производного класса, который добавляет свои собственные методы после базового класса.

Теперь вы можете создать аналогичный базовый класс «без дополнительных накладных расходов». По-видимому, GCC называет это «почти пустым».

+0

Звучит правдоподобно. У вас есть ссылка, чтобы подтвердить это? – Tobias