Размер класса без элементов данных возвращается как 1 байт, даже при том, что существует неявное 'этот' объявленный указатель. Не был должен размер, возвращенный быть 4 байта (на машине на 32 бита)? Я столкнулся со статьями, которые указали, что 'этот' указатель не считается для вычисления размера объекта. Но я не могу понять причину этого. Кроме того, если какая-либо функция членства объявляется виртуальная, размер класса теперь возвращается как 4 байта. Это означает, что vptr считается для вычисления размера объекта. Почему vptr рассматривают, и 'этот' указатель проигнорирован для вычисления размера объекта?
Указатель this
не является членом класса. Это просто конструкция, которая используется в методах, принадлежащих классу, для ссылки на текущий экземпляр.
Если у вас есть такой класс:
class IntPair
{
public:
IntPair(int a, int b) : _a(a), _b(b) { }
int sum() const { return _a + _b; }
public:
int _a;
int _b;
};
Этому классу требуется место только для двух экземпляров int
для каждого экземпляра. После того, как вы создали экземпляр и запустили метод sum ()
, этот метод вызывается с указателем на экземпляр, но этот указатель всегда приходит откуда-то еще, он не сохраняется в объекте. пример.
Например:
IntPair *fib12 = new IntPair(89, 144);
cout << fib12->sum();
Обратите внимание, как переменная, которая становится указателем this
, сохраняется вне объекта, в области, которая ее создала.
Фактически, вы всегда можете преобразовать метод, подобный приведенному выше, в:
static int sum2(const IntPair* instance)
{
return instance->_a + instance->_b;
}
Если указанный выше метод определен внутри класса (чтобы он мог получить доступ к закрытым членам), разницы нет. Фактически, это то, как методы реализуются за сценой; указатель this
- это просто скрытый аргумент для всех методов-членов.
Вызов будет выглядеть так:
IntPair* fib12 = new IntPair(89, 144);
cout << IntPair::sum2(fib12);
«this» не сохраняется как член данных в классе, это просто «указатель» на экземпляр класса. Считайте это «скрытым аргументом», переданным методу. Фактически, в системах Win32 он часто передается в регистре ecx (не eax, как я думал изначально).
Как только у вас есть 1 или несколько виртуальных методов, вашему приложению потребуется способ хранения указателей на виртуальные методы. Это называется vtable, которая идентична для всех экземпляров одного и того же класса. Поскольку вам нужно знать во время выполнения, какой «явный» метод вызывать, для какого «виртуального метода» указатель на vtable хранится в экземпляре класса. Следовательно, vtable-указатель (или vptr) требует 4 байта (или 8 байтов в 64-битной системе).
Указатель this не хранится внутри объекта. В этом нет необходимости. У вас уже есть указатель или объект для вызова функций. Что касается размера 1, стандарт C ++ требует, чтобы объекты distict имели разные адреса.