Pertimbangkan contoh ini:
#include <iostream>
int main()
{
struct A {};
struct B : A {};
struct C : A, B {};
std::cout << sizeof(A) << '\n'; // 1
std::cout << sizeof(B) << '\n'; // 1
std::cout << sizeof(C) << '\n'; // 2, because of a duplicate base
struct E : A {virtual ~E() {}};
struct F : A, B {virtual ~F() {}};
std::cout << sizeof(E) << '\n'; // 8, the base overlaps the vtable pointer
std::cout << sizeof(F) << '\n'; // 16, but why?
}
Di sini Anda dapat melihat bahwa untuk struct Ekelas dasar kosong (yang berukuran 1 byte) menggunakan penyimpanan yang sama dengan pointer vtable, seperti yang diharapkan.
Tetapi untuk struct F, yang memiliki basis kosong duplikat, ini tidak terjadi. Apa yang menyebabkan ini?
Saya mendapatkan hasil yang sama pada GCC, Dentang, dan MSVC. Hasil di atas adalah untuk x64, jadi sizeof(void *) == 8.
Menariknya, untuk struct G : A, B {void *ptr;};GCC dan Dentang lakukan melakukan EBO (ukurannya 8), tetapi MSVC tidak (ukurannya 16).
Cdan F? Bagaimanapun, 2 * sizeof(void*) == 16pada x86_64 seperti yang Anda katakan. Kompiler tidak dapat sepenuhnya mengoptimalkan (seperti yang dikatakan Story Teller) dan begitu juga tidak.
A, yang diwarisi melalui B, tidak dapat diakses. Ini baik saja. Hanya jika Anda benar-benar mencoba mengaksesnya, seperti dalam contoh Anda, Anda mendapatkan kesalahan.
C(yang mewarisi dariA,B) Anda mendapatkan hasil yang berbeda dari bentuk warisanAdanBlangsung