Что такое "почти пустой" класс? - PullRequest
2 голосов
/ 20 июля 2009

Скомпилируйте следующий класс

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)

Что означает «почти пустой»? Что это значит?

Ответы [ 4 ]

6 голосов
/ 20 июля 2009

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

6 голосов
/ 20 июля 2009

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

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

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

4 голосов
/ 30 июня 2010

C ++ ABI предоставляет определение "почти пустых" классов и интересное обсуждение того, как они влияют на конструирование vtable:

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

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

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

3 голосов
/ 20 июля 2009

Имеется только vtable, без полей данных.

...