Bu örneği düşünün:
#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?
}
Burada struct E, boş temel sınıf (1 bayt büyük) için beklendiği gibi vtable işaretçisiyle aynı depolamayı kullandığını görebilirsiniz.
Ancak struct F, yinelenen boş bir tabana sahip olduğu için , bu gerçekleşmez. Buna ne sebep olur?
Aynı sonucu GCC, Clang ve MSVC'de de alıyorum. Yukarıdaki sonuçlar x64 içindir sizeof(void *) == 8.
İlginçtir, struct G : A, B {void *ptr;};GCC ve Clang için EBO (boyut 8'dir), ancak MSVC yapmaz (boyut 16'dır).
Cve F? Sonuçta, 2 * sizeof(void*) == 16dediğin gibi x86_64 üzerinde. Derleyici tam olarak optimize edemez (Story Teller'ın dediği gibi) ve öyle değildir.
Aüzerinden devralınan ikinciye Berişilemediğini söyleyerek bir uyarı oluşturur . Bu iyi. Yalnızca örneğinizde olduğu gibi erişmeye çalışırsanız bir hata alırsınız.
C(hangi mirasA,B) formu devralan farklı bir sonuç eldeAveBdoğrudan