2017-01-26 6 views
0

다음 코드는 악명 높은 다이아몬드 상속을 보여줍니다. 그러나 적절한 참조 지정이 모호성을 피하는 것으로 보인다.참조로 다중 상속의 모호성을 어떻게 해결할 수 있습니까?

# include <iostream> 
# include <stdio.h> 

class B { 
public: 
    int m_a ; 
} ; 

class D1 : public B { } ; 

class D2 : public B { } ; 

class E : public D1, public D2 { } ; 

    int main() { 
    E e ; 
    D1& c = e ; 
    D2& d = e ; 

    e.D1::m_a = 2 ; 
    e.D2::m_a = 2 ; 

    std::cout << c.m_a << std::endl ; 
    std::cout << d.m_a << std::endl ; 

    c.m_a = 3 ; 
    std::cout << c.m_a << std::endl ; 
    std::cout << d.m_a << std::endl ; 

    printf ("%p\n", &c) ; 
    printf ("%p\n", &d) ; 
    printf ("%p\n", &e) ; 
    printf ("\n") ; 
    printf ("%p\n", (void*) &(c.m_a)) ; 
    printf ("%p\n", (void*) &(d.m_a)) ; 

    return 0 ; 
} 

출력은 다음과 같습니다

2 
2 
3 
2 
0xffffcbf0 
0xffffcbf4 
0xffffcbf0 

0xffffcbf0 
0xffffcbf4 

그래서 그것은 중복 D1 : m_a 및 D2가 들어있는 개체 'E'의 메모리 레이아웃에 시작해야하는 위치에 대한 참조가 '알고있다'보인다 :: m_a. C++ 구현에서 어떻게 달성되는지 궁금합니다. 감사!

+3

귀하의 계층 구조에는 다이아몬드가 없습니다 ... 그리고 여기에는 전혀 개념적으로 어려운 것이 없습니다. 그것은 단순히 이름 짓기에 * 지역적 모호성이있을 때 당신이 의미하는 바를 말하는 방법에 관한 질문 일뿐입니다. 구현에 관한 한, 이것은 'D1'과 'D2'가 다른 근거를 가지고있는 것과 다르지 않습니다. –

+0

이 부분에 대해 이야기하고 있습니까? 'E e; D1 & c = e; D2 & d = e;' –

+0

동일한 B를 사용하면 다이아몬드가됩니다. 이렇게하려면 가상 상속을 사용해야합니다. 지금 당신은 단지 두 개의 객체, 즉 D1과 D2를 가질 수 있습니다. – dascandy

답변

1

무슨 일이 일어나는지를 가장 쉽게 발견하는 방법은 (void*)(&c)(void*)(&d)입니다. 두 참조는 e의 고유 한 하위 객체를 참조합니다.

또한, D1D2에 대한 참조 할 은 일부 E 안에 거 알아하지. 참조는 메모리에있는 모든 객체를 참조 할 수 있지만 객체의 주변에 대해서는 알지 못합니다.

+0

이것은 정확히 내가 묻는 바입니다. 그리고 지금까지 이해할 수있는 한 : 프로그램은 항상 'D2 & d = e' 또는'D1 & c = e' 선언 중에 '포인터'를 Base 클래스에 따라 위치를 지정합니다. 내가 제대로 이해하는지 모르겠다. – Roy

+0

글쎄, 선언은 포인터가 아니라 참조 선언이며, 그렇지 않으면 올바른 것입니다. ('&'address-of 연산자를 사용하여 참조로부터 포인터를 얻을 수 있습니다) – MSalters