Функции-члены, по сути, такие же, как и обычные функции, они просто получают скрытый параметр this
. Таким образом, каждый экземпляр данного типа не должен носить с собой копии своих функций-членов; компилятор просто отслеживает обычные функции и предоставляет соответствующий параметр this
для вас. Поэтому независимо от того, сколько функций имеет данный тип, нет необходимости изменять его размер. Когда вы попадаете в сложное наследование с виртуальными функциями и так далее, это немного меняется, но, в конце концов, количество функций по-прежнему не влияет на конечный размер объекта.
Первоначальный размер одного байта объясняется тем, что все объекты должны занимать некоторое пространство, так что вы можете быть уверены, что два объекта не займут одно и то же пространство. Рассмотрим массив ... a[5]
- это то же самое, что и *(a + 5)
, и добавление к указателю увеличивает адрес памяти на размер объекта. если бы sizeof(a)
было 0
, то все элементы массива свернулись бы по одному и тому же адресу.
То, что тип объектов некоторого пространства определяется стандартом ... что размер, равный точно одному, не равен. sizeof(c)
в вашем случае может быть 23, но для этого нет причин.
Для полноты картины подобъект может иметь нулевой размер. Оптимизация пустой базы позволяет базовому классу не занимать никакой фактической памяти, если в этом нет необходимости. Так что sizeof(Base) == sizeof(Derived)
может быть правдой, хотя формально Derived
содержит экземпляр Base
, скрытый внутри него. Это разрешено стандартом, но не предписано им ... MSVC, например, не использует его в некоторых ситуациях.