빈 기본 최적화 가 훌륭합니다. 그러나 다음과 같은 제한 사항이 있습니다.
비어있는 기본 클래스 중 하나가 첫 번째 비 정적 데이터 멤버의 유형이거나 해당 유형 인 경우 비어있는 기본 최적화는 금지됩니다. 동일한 유형의 두 기본 서브 오브젝트는 오브젝트 표현 내에서 다른 주소를 가져야하기 때문입니다. 가장 많이 파생 된 유형의
이 제한을 설명하려면 다음 코드를 고려하십시오. 는 static_assert
실패합니다. 반면, 변화 중 하나 Foo
또는 Bar
대신 상속에 Base2
오류를 피하기합니다 :
#include <cstddef>
struct Base {};
struct Base2 {};
struct Foo : Base {};
struct Bar : Base {
Foo foo;
};
static_assert(offsetof(Bar,foo)==0,"Error!");
이 동작을 완전히 이해합니다. 내가 이해 하지 못하는 것은 이 특정한 행동 이 존재하는 이유 입니다. 그것은 명백한 이유가 아니라 감독에 의한 것이 아니기 때문에 분명한 이유로 추가되었습니다. 이에 대한 근거는 무엇입니까?
특히 두 기본 하위 오브젝트에 다른 주소가 필요한 이유는 무엇입니까? 위 Bar
의 유형은 유형이며 foo
해당 유형의 멤버 변수입니다. 왜 Bar
기본 클래스의 유형이 기본 클래스의 유형 foo
인지 또는 그 반대인지는 알 수 없습니다.
실제로 다른 상황에서도 필요하므로 인스턴스가 포함 &foo
된 Bar
인스턴스 의 주소와 동일한 것으로 예상 됩니다 (1) . 결국, 나는 virtual
상속으로 공상을하지 않고 기본 클래스는 비어 있으며, 컴파일 Base2
은이 특별한 경우에 아무것도 깨지지 않는다는 것을 보여줍니다.
그러나 분명히이 추론은 어쨌든 부정확하며,이 제한이 필요한 다른 상황이 있습니다.
대답은 C ++ 11 이상이어야합니다 (현재 C ++ 17을 사용하고 있습니다).
(1) 참고 : EBO는 C ++ 11에서 업그레이드되었으며 특히 StandardLayoutType
s의 경우 필수가되었습니다 ( Bar
위의 a는 아닙니다 StandardLayoutType
).
Base *a = new Bar(); Base *b = a->foo;
로a==b
하지만,a
그리고b
명확하게 (아마도 다른 가상 메서드 재정의와) 다른 개체입니다.