Стандарт обязывает разные объекты одного типа иметь разные адреса. Это, в свою очередь, гарантирует, что для любого объекта T
, T*
действует как однозначный идентификатор этого объекта (для этого типа).
Конечно, вам не нужно часто знать, действительно ли два объекта одинаковы или нет, но иногда (с учетом низкоуровневого доступа C ++) это либо необходимо, либо просто удобно.
Таким образом, указано, что ни один объект не должен иметь нулевой размер.
Однако из этого правила есть исключение: при использовании пустого класса в качестве базового класса компилятор может выбрать применение Empty Base Optimization ( EBO ) в некоторых случаях. Например:
struct Empty {};
struct Slim: Empty {
int a;
};
static_assert(sizeof(Slim) == sizeof(int), "");
Как правило, размер базового класса добавляется, но в данном конкретном случае это не является необходимым. Однако правило о том, что два разных объекта одного типа никогда не должны иметь один и тот же адрес, по-прежнему применяется, и поэтому:
struct Fat: Empty {
Empty e;
};
static_assert(sizeof(Fat) > sizeof(Empty), "");
EBO является основной причиной использования наследования private
в шаблонных ситуациях. Например:
template <typename Allocator>
class MyClass: private Allocator {
};
Таким образом, если окажется, что Allocator
- пустой класс, никаких накладных расходов не будет. В общем, поэтому он часто используется для политик , например, предикатов, которые вы передаете map
.