Не очень важно знать, как именно C
размещается и дополняется, поскольку это определяется реализацией и будет различаться на разных платформах. Но есть одна специфическая деталь...
Базовый класс A
, будучи фактически унаследованным, извлекается на вершину иерархии. Так что это часть B1
только до тех пор, пока B1
используется сам по себе. Когда он наследуется внутри C
, A
больше не является его частью.
Это означает, что мы не можем полагаться на sizeof(B1)
или sizeof(B2)
, так как сначала нужно вычесть из них sizeof(A)
. Но удаление 4 байтов из B1
не уменьшит его размер с 16 до 12, поскольку он должен быть выровнен и дополнен до 8 байтов (при условии, что он 64-битный) из-за vbptr.
Таким образом, мы получаем sizeof(B1 less A)
+sizeof(B2 less A)
+sizeof(A)
+sizeof(C::c)
= 16+16+4+4 = 40.
Мы можем получить необычный результат, если увеличим A
:
#include <iostream>
using namespace std;
class A {
int a1,a2,a3,a4,a5;
};
class B1 : virtual public A {
int b1;
};
class B2 : virtual public A {
int b2;
};
class C : public B1, public B2 {
int c;
};
int main() {
A obj1; B1 obj2; B2 obj3; C obj4;
cout << "sizeof(A) = " << sizeof(obj1) << endl;
cout << "sizeof(B1) = " << sizeof(obj2) << endl;
cout << "sizeof(B2) = " << sizeof(obj3) << endl;
cout << "sizeof(C) = " << sizeof(obj4) << endl;
return 0;
}
Распечатки:
sizeof(A) = 20
sizeof(B1) = 32
sizeof(B2) = 32
sizeof(C) = 56
Теперь более понятно, что sizeof(C)
‹ sizeof(B1)
+ sizeof(B2)
.
Чтобы узнать больше, вы можете поиграть со смещениями, чтобы увидеть, как именно расположено C
.
person
rustyx
schedule
08.01.2021
int
. Что там выравнивать или прокладывать? - person Spencer   schedule 08.01.2021vptr
составляет 8 байт. - person Yksisarvinen   schedule 08.01.2021vptr
, предполагающем 32-битную архитектуру. Связанный вопрос не касается vptr в виртуальном наследовании, поэтому, возможно, вам следует опубликовать ответ здесь. - person Spencer   schedule 08.01.2021A
также естьint
. - person Spencer   schedule 08.01.2021sizeof()
, который не соответствует их ожиданиям. Мол, эй, ты не должен давать мне такой ответ. - person PaulMcKenzie   schedule 08.01.2021sizeof(int)
+ заполнение до числа, кратного 8, для требования выравнивания указателей. - person molbdnilo   schedule 08.01.2021sizeof(int)
иsizeof(void*)
- person curiousguy   schedule 08.01.2021