C++, 다중상속, dynamic_cast
글쓴이: wafe / 작성시간: 금, 2004/04/30 - 12:47오후
클래스 A가 있습니다. 그리고 인터페이스 흉내를 내려고 클래스 B를 만들어서 가상함수만 넣었습니다. 그리고 C는 A와 B를 상속 받아서 가상 함수를 구현했습니다.
class A { public: void MethodA1(); }; class B { public: virtual void MethodB1() = 0; }; class C : public A, B { void MethodB1() { // blahblah } };
그 외에도 같은 형식으로 A,B를 상속받아 B의 가상 함수를 구현한 클래스들이 많습니다. D, E, F, ...
그리고 함수가 하나 있는데 이 함수가 A형 포인터를 받는데, 실제로는 항상 C, D, E, F 등등 상속된 클래스만 받습니다. 그런데 이 함수에서 내부에서 B의 포인터로 바꿀 일이 있습니다. B*형을 받는 다른 함수를 호출해야 하거든요. 대충 이런 식이지요.
func1(A* pA) { // 조건 1 if(...) { B* pB = dynamic_cast<B*>(pa); func2(pB); } else { // 딴짓 } }
이 코드에서 dynamic_cast 가 실패하는 것이 정상인가요? 반환값이 NULL이 나와서 pB를 쓸 수가 없네요. 그리고 이 경우에 C 스타일 캐스팅을 사용하면 문제가 발생하지는 않을까요?
Forums:
Re: C++, 다중상속, dynamic_cast
A 와 B 타입은 아무 관계가 없습니다.
해서 상호간 캐스팅도 불가능합니다.
그래서 dynamic_cast 가 NULL 을 리턴할 것입니다.
C 스타일 캐스팅을 써서도 안됩니다.
A 포인터를 B 포인터로 바꾸기 위해서는
A 포인터를 C 와 같이 A 와 B 간의 관계를 가지고 있는 포인터로 바꾼 다음
C 포인터를 B 포인터로 바꾸는것이 바른 방법입니다.
참고로 가상테이블을 가진 클래스들의 다중상속시
실제 인스턴스는 동일하다 해도,
참조하는 타입에 따라 값이 달라집니다. (아래 예제 참고)
아래 예에서는 reinterpret_cast 를 사용하였지만,
만약 p1 포인터를 p2 로 변환시 C style cast 를 사용한다면
결과는 reinterpret_cast 로 변환한것과 같을 것입니다.
클래스 A와 B는 서로 관계가 없으므로 직접 dynamic_cast를 하
클래스 A와 B는 서로 관계가 없으므로 직접 dynamic_cast를 하면
항상 0이 나옵니다. 그러나 A*가 가리키는 개체가 C라는 것을 알고
있다면 안전하게 B*로 바꿀 수 있습니다.
댓글 달기