이 예제를 고려하십시오.
#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?
}
여기 struct E에서 비어있는 기본 클래스 (1 바이트)는 예상대로 vtable 포인터와 동일한 스토리지를 사용합니다.
그러나 struct F빈베이스가 중복 된에 대해서는 이런 일이 발생하지 않습니다. 무엇이 원인입니까?
GCC, Clang 및 MSVC에서 동일한 결과를 얻습니다. 위의 결과는 x64에 대한 것 sizeof(void *) == 8입니다.
흥미롭게도 struct G : A, B {void *ptr;};GCC와 Clang의 경우 EBO를 수행하지만 (크기는 8) MSVC는 수행하지 않습니다 (크기는 16).
C과 에서 파생 된 애매함에서 비롯된 것일 수 F있습니까? 결국, 2 * sizeof(void*) == 16x86_64에서 말했듯이. 컴파일러는 Story Teller가 말했듯이 완전히 최적화 할 수 없으므로 그렇게 최적화 할 수 없습니다.
A는를 통해 상속 된 두 번째 에 B액세스 할 수 없다는 경고 만 표시합니다 . 괜찮습니다. 예제와 같이 실제로 액세스하려고 시도하는 경우에만 오류가 발생합니다.
C(어떤이 상속A,B) 당신은 폼 상속과는 다른 결과를 얻을 수A및B직접