본문 바로가기

C++

다중 상속(Diamond of Death)의 문제점

다중상속은 하나의 클래스가 여러 클래스를 상속 받는 것을 의미한다.

단, 상속의 상속을 받는 형태가 아니다. 아래와 같은 코드를 다중 상속이라 한다.

class AAA
{
}

class BBB
{
}

class CCC : public AAA, public BBB
{
}

자식 클래스(CCC Class)는 AAA, BBB 클래스를 상속받는다. 이런 형태를 두고 다중 상속이라 한다.

위와 같은 멤버가 아무것도 없는 클래스에 대하여는 "무슨 문제가 발생하지?" 라는 의문이 생길 수 있다.

 

다중 상속의 문제점 - 1

class AAA
{
public:
    int m_iData;
};

class BBB
{
public:
    int m_iData;
};

class CCC : public AAA, public BBB
{
};

int main()
{
    CCC instC = CCC();
    
    // m_iData가 AAA, BBB 어떤 클래스의 변수인지 모호하다.
    int getData = instC.m_iData;     
    
    return 0;
}

다중 상속의 문제점 - 2 

class AAA
{
public:
    int m_iData;
};

class BBB : public AAA
{
};

class CCC : public AAA
{
};

class DDD : public BBB, public CCC
{
};

int main()
{
    DDD instC = DDD();
	
    // m_iData가 BBB, CCC 어떤 클래스의 변수인지 모호하다.
    int getAData = instC.BBB::m_iData;
    int getBData = instC.CCC::m_iData;

    return 0;
}

DDD 클래스가 사용하는 m_iData가 BBB, CCC 사이에서의 모호성이 발생한다.

다중 상속 해결 방법 - 명시적 해결 방법

자신이 사용할 m_iData가 어떤 클래스의 멤버를 사용하는지 스코프 분석 연산자(::)를 이용하여 접근하는 방법이다.

int main()
{
    DDD instC = DDD();	
    int getAData = instC.BBB::m_iData;
    int getBData = instC.CCC::m_iData;

    return 0;
}

다중 상속 해결 방법 - Virtual 상속

AAA 클래스를 상속받는 BBB, CCC 클래스는 AAA 클래스를 상속받을 때 virtual 키워드를 붙여 상속을 하면 AAA 클래스

안에 존재하는 멤버들은 한번만 상속이 이뤄진다. 아래 코드에서는 BBB 클래스가 AAA 클래스의 멤버를 상속받는다.

class AAA
{
public: 
    AAA()  { cout << "생성자 A" << endl; }
    ~AAA() { cout << "소멸자 A" << endl; }

public:
    int m_iData;
};

class BBB : virtual public AAA
{
public:
    BBB()  { cout << "생성자 B" << endl; }
    ~BBB() { cout << "소멸자 B" << endl; }
};

class CCC : virtual public AAA
{
public:
    CCC()  { cout << "생성자 C" << endl; }
    ~CCC() { cout << "소멸자 C" << endl; }
};

class DDD : public BBB, public CCC
{
public:
    DDD()  { cout << "생성자 D" << endl; }
    ~DDD() { cout << "소멸자 D" << endl; }
};

int main()
{
    DDD instC = DDD();
	
    // B.m_iData의 값을 호출하게 된다.
    int getData = instC.m_iData;

    return 0;
}

다중 상속에서의 생성자, 소멸자 순서

생성자 순서 : A -> B -> C -> D

소멸자 순서 : D -> C -> B -> A