Как определяется размер класса в C ++ при использовании виртуального ключевого слова и наследования? - PullRequest
0 голосов
/ 21 сентября 2018

Я пытаюсь полностью понять, как размеры классов определяются в C ++, поэтому я могу помнить об этом при проектировании структур данных.У меня есть несколько классов, которые я создал для тестирования, но мне кажется, что он борется с некоторыми размерами, возможно, из-за незнания порядка, в котором складываются размеры.

При 64-битной компиляции учтите следующее.

class A {
public:
    virtual void work() {}

private:
    float a;
    float b;
};

class B : A {
private:
    float b1;
};

class C : A {
private:
    float c1;
};

class D : C {
private: 
    float d1;
};

struct DCA {
    float d1;
    float c1;
    float a;
    float b;
    void* function;
};

int main()
{
    std::cout << sizeof(A) << std::endl;//16
    std::cout << sizeof(B) << std::endl;//24
    std::cout << sizeof(C) << std::endl;//24
    std::cout << sizeof(D) << std::endl;//32
    std::cout << sizeof(DCA) << std::endl;//24;
}

Теперь я понимаю, что указатель создается при использовании виртуальной функции, которая на 64-битной основе добавляет 8 байтов.

  1. Этот указатель предназначен только для классакоторый имеет виртуальную функцию, или производный класс также.

  2. В каком порядке я бы рассчитал размер.Если бы я вычислял размер D, я бы начал с вычисления размера A, затем C, тогда D?

  3. struct DCA имеет те же переменные, что и класс D, однакоего размер равен 24, а размер класса D равен 32. Я бы ожидал, что D также будет равен 24, так как я сначала считаю число с плавающей запятой, которое составляет 16 байтов, а затем 8 байтов для указателя.24 делится на 8, что соответствует 8 байтам.

Может кто-нибудь попытаться ответить на эти вопросы и сказать мне, где я ошибаюсь с моей логикой?

enter image description here


Повторяющийся вопрос не касается виртуального ключевого слова, наследования или порядка вычислений.Также не упоминается, есть ли стандартное специфическое выравнивание байтов.

1 Ответ

0 голосов
/ 21 сентября 2018

Является ли этот указатель только для класса, который имеет виртуальную функцию, или для производного класса.

Поскольку производный класс содержит базовый класс в качестве своего подобъекта, производныйКласс также имеет этот указатель на vtable.

В каком порядке я бы рассчитал размер.Если бы я вычислял размер D, я бы начал с вычисления размера A, затем C, затем D?

От основания к производному.Для нескольких базовых классов слева направо.Это связано с тем, что перед первым элементом нет отступов.

struct DCA имеет те же переменные, что и класс D

Они имеют одинаковый размер, а именно 24 байта.

...