반응형


보통은 자식 클래스가 자신의 부모 클래스의 생성자만 호출 가능하고, 할아버지 클래스의 생성자를

호출 할 수 없지만, 가상 기반 클래스 에서는 예외가 있습니다...

즉, 손자 클래스가 자신의 부모보다도 상위인 할아버지 클래스의 생성자를 호출 할 수

있다는 점이죠...

또한, 이 경우에 있어서는 중간 클래스를 의미하는 부모 클래스(class XY, class XZ) 에서는 비록...

최상위 클래스의 생성자를 호출하는 코드인 CPointX(a) 가 XY, XZ 클래스의 생성자 초기화 리스트에

있지만, 손자 클래스인 XYZ 클래스의 생성자 초기화 리스트 부분에서...단 "한 번만" 호출된다는

점 입니다...

브레이크 포인트를 걸어서 코드 흐름을 추적해 보면 알겠지만, 위 코드에선 CPointX(a) 부분이 한 번 밖에

호출되지 않고, 이를 담당하는 것은 손자 클래스인 XYZ 클래스 입니다...

정리하면,,,가상 기반 상속에서는 손자 클래스에서 할아버지 클래스의 생성자를 직접 호출한다는

점이고, 중간 클래스인 부모 클래스에서는 비록, 그 상위 클래스의 생성자를 호출하는 코드가

있다고 하더라도 호출되지 않는다는 점 입니다...

또한...가상 상속을 사용하는 이유는 할아버지 클래스인 X 클래스를 상속받는 XY, XZ 클래스를 XYZ 라는

클래스가 상속받기 때문에...XYZ 입장에서는 X 클래스의 멤버가 어디에서 온 멤버인지 모호하기 때문에

이 가상상속을 사용하여, 모호함을 없애는 것입니다...

X X

| |

XY XZ

XY, XZ 를 상속받는 XYZ 클래스는 X의 멤버를 참조할 때 XY 에서 온 X인지, XZ 에서 온 X인지

모호함으로 인해 판단하기 어렵다는 점입니다...

그래서...이를 해결하고자 가상상속을 사용하는 것이고, 손자 클래스가 할아버지 클래스의 생성을

직접 담당하는 것입니다...

코드를 다음과 같이 수정 합니다...

class CPointXY : virtual public CPointX{

.....

// CPointX(a) 생성자는 여기에서 호출되지 않는다.

CPointXY(int a, int b) : CPointX(a), y(b)

};

class CPointXZ : virtual public CPointX{

.....

// CPointX(a) 생성자는 여기에서 호출되지 않는다.

CPointXZ(int a, int c) : CPointX(a),z(c)

};

class CPointXYZ : public CPointXY, public CPointXZ{

...

// 할아버지 클래스의 생성자를 직접 호출한다

// 만약, CPointX(a) 를 명시적으로 호출하는 코드가 없다면 할아버지 클래스인

// CPointX 클래스에 인자를 가지지 않는 디폴트 생성자가 있어야 합니다...

CPointXYZ(int a, int b, int c) : CPointX(a), CPointXY(a,b), CPointXZ(a,c), xyz(0)

...

};





출처 : 

http://kin.naver.com/qna/detail.nhn?d1id=1&dirId=1040101&docId=76771879&qb=7KaJLCDshpDsnpAg7YG0656Y7Iqk6rCAIOyekOyLoOydmCDrtoDrqqjrs7Tri6Trj4Qg7IOB7JyE7J24IO2VoOyVhOuyhOyngCDtgbTrnpjsiqTsnZgg7IOd7ISx7J6Q66W8IO2YuOy2nCDtlaAg7IiYIOyeiOuLpOuKlCDsoJDsnbTso6AuLi4=&enc=utf8&section=kin&rank=1&search_sort=0&spq=0&pid=R5vBMF5Y7uKsscvCnRhssc--453720&sid=UJDjOsm@kFAAAHDkOiE

반응형

+ Recent posts