Почему классы C ++ без переменных-членов занимают место?
Я обнаружил, что компиляторы MSVC и GCC выделяют как минимум один байт на каждый экземпляр класса, даже если класс является предикатом без переменных-членов (или только с статическими переменными-членами). Следующий код иллюстрирует суть.
#include <iostream>
class A
{
public:
bool operator()(int x) const
{
return x>0;
}
};
class B
{
public:
static int v;
static bool check(int x)
{
return x>0;
}
};
int B::v = 0;
void test()
{
A a;
B b;
std::cout << "sizeof(A)=" << sizeof(A) << "\n"
<< "sizeof(a)=" << sizeof(a) << "\n"
<< "sizeof(B)=" << sizeof(B) << "\n"
<< "sizeof(b)=" << sizeof(b) << "\n";
}
int main()
{
test();
return 0;
}
Выход:
sizeof(A)=1
sizeof(a)=1
sizeof(B)=1
sizeof(b)=1
Мой вопрос: зачем это нужно компилятору? Единственная причина, по которой я могу придумать, - убедиться, что все указатели var-членов отличаются, чтобы мы могли различать два члена типа A или B, сравнивая с ними указатели. Но цена этого довольно высока при работе с небольшими контейнерами. Учитывая возможное выравнивание данных, мы можем получить до 16 байт на класс без переменных (?!). Предположим, у нас есть собственный контейнер, который обычно будет содержать несколько значений типа int. Затем рассмотрим массив таких контейнеров (около 1000000 членов). Накладные расходы будут 16 * 1000000! Типичный случай, когда это может произойти, - контейнерный класс с предикатом сравнения, хранящимся в переменной-члене. Кроме того, учитывая, что экземпляр класса всегда должен занимать некоторое пространство, какого типа издержки следует ожидать при вызове A () (значение)?