Почему размер производного класса при множественном наследовании не включает его собственный виртуальный указатель?

#include<iostream>

using namespace std;

class A
{
    virtual void fun() {}
};

class B
{
    virtual void fun2() {}
};
class C : virtual public  A, virtual public B
{
    public:
        virtual void fun3() {}
};


int main()
{

    /**
     * why is the size of C 16 and not 24?
     */
    cout<<sizeof(A)<<" "<<sizeof(B)<<" "<<sizeof(C);

    return 0;
}

Я не понимаю, почему размер C равен 16, а не 24. Если он наследует виртуальные указатели как класса A, так и B, то почему у него нет собственного виртуального указателя?


person Yueyang Pan    schedule 30.06.2020    source источник
comment
Сделайте класс с 1 функцией, затем класс с 10 функциями ... Есть ли разница в размере? ;) godbolt.org/z/_fNBBA   -  person ChrisMM    schedule 30.06.2020
comment
Скорее всего, он оптимизирован.   -  person Michael Chourdakis    schedule 30.06.2020
comment
Я думаю, что по умолчанию класс помещает все свои атрибуты / функции в частный режим. Вы уверены, что класс C имеет доступ к функциям своих родителей?   -  person Sunchock    schedule 30.06.2020
comment
@Sunchock, можно ли получить к ним доступ или нет, они все еще там   -  person 463035818_is_not_a_number    schedule 30.06.2020
comment
Отвечает ли это на ваш вопрос? Стоимость памяти таблицы виртуальных функций C ++   -  person user1810087    schedule 30.06.2020
comment
@ idclev463035818 Вы правы, но мне было интересно, не играет ли это с оптимизацией и вдруг может окончательный размер   -  person Sunchock    schedule 30.06.2020
comment
Дополнение: вопрос может означать что-то другое, например: если C наследует указатели на vtable от A и B и имеет указатель на свою собственную vtable, почему размер не 3 указателя (24 байта в этом кейс). По этой причине компилятор может расширить унаследованную vtable, поэтому класс C по-прежнему имеет только 2 указателя на vtables, A и B, но к одному из них добавлена ​​другая виртуальная функция (fun3). Источник: как определить класс sizeof с виртуальными функциями?   -  person user1810087    schedule 30.06.2020
comment
Компилятор, вероятно, организует vtables более разумным способом, чем вы. Вероятно, он распознает, что и A, и B имеют одну виртуальную функцию, и помещает указатель для fun3() в свободное пространство в одном или обоих унаследованных vtables. В конце концов, код, который использует C (например, вызывает object->fun3(), где object указывает на экземпляр C или класс, производный от C), показывает, что C имеет две базы, каждая из которых имеет только одну виртуальную функцию.   -  person Peter    schedule 30.06.2020
comment
Это регулируется ABI, а не стандартом C ++. См. Категория 3: Только виртуальные базы в itanium-cxx-abi. github.io/cxx-abi/abi.html#vtable   -  person Maxim Egorushkin    schedule 30.06.2020
comment
FWIW, я не думаю, что виртуальное наследование здесь правильное. Виртуальное наследование обычно помогает решить проблему с алмазом это не совсем то, что вы здесь делаете. Я думаю, вы хотите вместо этого нормальное наследование.   -  person    schedule 01.07.2020