'polymorphic'에 해당되는 글 1건

  1. 2012.10.31 dynamic_cast : Polymorphic 클래스 기반의 형 변환

# 상속관계에 놓여있는 두 클래스 사이에서, 유도 클래스의 포인터 및 참조형 데이터를 기초 클래스의 포인터 및 참조형 데이터로 형 변환할 경우에는 dynamic_cast 연산자를 사용한다.


# 상속관계에 놓여있는 두 클래스 사이에서, 기초 클래스의 포인터 및 참조형 데이터를 유도 클래스의 포인터 및 참조형 데이터로 형 변환할 경우에는 static_cast 연산자를 사용한다.



하지만, 다음의 조건만 만족하면!! dynamic_cast 연산자도 기초 클래스의 포인터 및 참조형 데이터를 유도 클래스의 포인터 및 참조형으로의 형 변환을 허용한다.


"기초 클래스가 'Polymorphic Class' 이다."



Polymorphic 클래스란, 하나 이상의 가상함수를 지니는 클래스를 뜻한다. 그러니 상속관계에 놓여있는 두 클래스 사이에서 기초 클래스에 가상함수가 하나 이상 존재하면, dynamic_cast 연산자를 이용해서 기초 클래스의 포인터 및 참조형 데이터를 유도 클래스의 포인터 및 참조형 데이터로 변환이 가능하다.


 

13행: Simple 클래스가 Polymorphic 클래스이므로 Complex 클래스도 Polymorphic 클래스이다.

24행: 포인터 변수가 가리키는 것은 Complex 객체이다.

25행: 기초 클래스인 Simple이 Polymorphic 클래스이므로 dynamic_cast 연산자로 형 변환이 가능하다.


위의 main함수에서 dynamic_cast 연산이 성공한 이유는?


-> 포인터 변수 simPtr이 실제 가리키는 객체가 Complex 객체이기 때문이다. 즉, 포인터 변수 simPtr이 가리키는 객체를 Complex 형 포인터 변수 comPtr이 함께 가리켜도 문제되지 않기 때문에 성공한 것이다.



만약, 안정적이지 못한 형 변환을 시도할 경우, dynamic_cast는 NULL 포인터가 반환된다.



이렇듯 dynamic_cast는 안정적인 형 변환을 보장한다. 특히 컴파일 시간이 아닌 실행 시간에(프로그램이 실행중이 동안에) 안전성을 검사하도록 컴파일러가 바이너리 코드를 생성한다는 점에 주목할 필요가 있다. 

물론 이로 인해서 실행속도는 늦어지지만, 그만큼 안정적인 형 변환이 가능한 것이다. 그리고 이러한 특성 때문에 연산자의 이름이 dynamic으로 시작하는 것이다.


static_cast는 안전성을 보장하지 않는다. 컴파일러는 무조건 형 변환이 되도록 바이너리 코드를 생성하기 때문에, 그로 인한 실행의 결과는 전적으로 프로그래머가 책임져야 한다. 그래서 이러한 특정 때문에(실행중인 동안에 안전성 검사를 진행하지 않는 특성때문에) 연산자의 이름이 static으로 시작하는 것이다. 

물론, 실행속도는 빠르다. 실행 시간에 안전성 검사를 별도로 진행하지 않기 때문이다. 






bad_cast 예외


- 프로그래머가 정의하지 않아도 발생하는 예외.

bad_cast 예외는 dynamic_cast 연산자를 이용한 형 변환의 과정에서 발생할 수 있는 예외이다.




29행: 참조자 ref가 실제 참조하는 대상이 Simple 객체이기 때문에 Complex 참조형으로의 형 변환은 안전하지 못하다. 그리고 참조자를 대상으로는 NULL을 반환할 수 없기 때문에 이러한 상황에서는 bad_cast 예외가 발생한다.


※ 위 예제에서 보이듯이, 참조형을 대상으로 dynamic_cast 연산을 진행할 경우에는 bad_cast 예외가 발생할 수 있기 때문에 반드시 이에 대한 예외처리를 해야 한다.


Posted by scii
: