요즘 C++의 virtual 메카니즘에 빠져서 산다. virtual.. 그리 오랜시간 보아왔는데도, 여전히 어렵다.. 다음은 오늘 알아낸 것들.
-
RTTI(Run-Time Type Identification), 실행 중에 기반(base) 클래스 타입 포인터의 실체를 밝혀내는데 쓰이는
typeid연산자. 그 기반 타입의 포인터가 다형성을 지닌 클래스(polymophic class), 즉 "virtual 함수가 있는 클래스"가 아니면 아무짝에도 쓸모가 없다. "typeid(기반 타입의 포인터)" 해보았자, 보이는 그대로 그 기반 타입임만을 알려줄 뿐, 실제 담겨있는 타입, 즉 그 기반 타입의 포인터로부터 파생된 타입(derived type)에 대해서는 알려주는 바가 없다. -
dynamic_cast연산자는 반드시 polymophic class에 사용해야 한다. polymophic class가 아닌 클래스에 사용할 경우에는 컴파일 오류(Visual C++의 경우, C2683 컴파일 오류 -dynamic_cast : 'type' is not a polymorphic type.)를 낸다. (이 때는static_cast로 대체하여 사용하면 되더라..) -
기반 클래스 타입의 포인터로 자식 클래스 객체를
delete연산자로써 소멸시킬 경우, 역시나 기반 클래스가 polymophic class가 아니면 기반 클래스 부위만 소멸될 뿐, 파생 클래스 부위는 소멸되지 않는다.다음은 예제 코드다.
C++#include <typeinfo> #include <iostream> using namespace std; class base { public: base() { cout << "base contructed." << endl; } virtual ~base() { cout << "base destructed." << endl; } }; class derived : public base { public: derived() { cout << "derived contructed." << endl; } ~derived() { cout << "derived destructed." << endl; } }; int main() { derived* pD = new derived; base* pB = pD; derived* pD1 = dynamic_cast<derived*>(pB); if( typeid(*pB) == typeid(derived) ) cout << "OK!" << endl; else cout << "No!" << endl; delete pB; }다음은 출력 결과.
C++base constructed. derived constructed. OK! derived destructed. base destructed.위 예제 코드 중,
base클래스의 소멸자에virtual이 없다면,dynamic_cast가 담긴 문장에서 c2683 컴파일 오류가 난다.- 위
dynamic_cast가 담긴 문장을 제거한다고 해도,
출력 결과는
OK!가 아닌No!이며,- 마지막
delete연산에서는 생성된derived객체의base부위만이 소멸되고derived만의 고유 부위는 그대로 남아, memory leak이 발생한다.
다음은
base클래스의 소멸자에virtual키워드를 제거하고,dynamic_cast가 담긴 문장을 주석 처리했을 경우의 출력 결과.
C++base constructed. derived constructed. No! base destructed.

Comments