2017-02-07 16 views
0

나는 비 다이아몬드 상속의 효과 다이아몬드 상속 트리에서 가상 상속 아니라 부작용 (있는 경우)를 이해 나무.가상 상속 - 메모리 및 행동 부작용

class A 가정 그냥 행동 또는 생성자 호출 순서, 즉 메모리 레이아웃 (있는 경우)이 두 클래스에서가 어떤 차이

class A; 

class B: public virtual A; 

가있는 경우 데이터 회원이 있습니다.

답변 가상 상속의

+0

그것은 동일한 방식으로 작동 : 다른 한편으로, 가상이 아닌 기본의 데이터 멤버에

class A { public: int a; }; class B : public virtual A { public: int b; }; int main() { B b; std::cout << "&b.a < &b.b = " << (&(b.a) < &(b.b)) << std::endl; // &b.a < &b.b = = 0 return 0; } 

보통 아이의 데이터 멤버 전에 를 배치 다이아몬드가 있는지 없는지. – NathanOliver

+1

표준에서 구현 세부 사항을 위임 할 것인지 의심 스럽습니다. AFAIK, vtable을 사용할 필요조차하지 않습니다 (대부분은 그렇지만). – OMGtechy

+0

@NathanOliver 예제에서 어떤 동작입니까? – Adrian

답변

2

한 효과를 공식 문서를 static_cast으로 downcasting하는 것은 작동하지 않는다는 것입니다 주시기 바랍니다. 가상 기반에서 다운 캐스트하려면 dynamic_cast을 대신 사용해야합니다. 표준에서 인용

A* pa = new B; 
B* pb1 = static_cast<B*>(pa); // doesn't work: compilation error 
B* pb2 = dynamic_cast<B*>(pa); // works 

(5.2.9)

B 클래스 타입 "CV1의 B, 포인터 '유형의 prvalue 입력의 prvalue로 전환시킬 수있다"포인터 B 는 D의 가상 기본 클래스와 메모리 레이아웃에 대해서는 D.

+0

예! 이것은 제가 찾고 있던 정보의 종류입니다. – Adrian

0

의 가상 기본 클래스의 기본 클래스도는 ... 경우 CV2의 D "에 ..., 어떤 컴파일러가 배치 될 가능성이 가상베이스의 데이터 멤버 이후 서브 클래스의 데이터 멤버 (Multiple Inheritance Considered Useful 참조)

class A { 
public: 
    int a; 
}; 

class B : public virtual A { 
public: 
    int b; 
}; 

int main() { 
    B b; 

    std::cout << "&b.a < &b.b = " << (&(b.a) < &(b.b)) << std::endl; // &b.a < &b.b = 1 

    return 0; 
}