다이나믹 캐스트

김대익·2022년 3월 7일

RTTI(runtime type information)
c++에서는 RTTI를 사용하는 것을 피하라고 권고한다.



derived 클래스에서 base 클래스로 변환하는 것을 upcast
반대를 downcast라고 부른다.


이 Animal을 상속받는

Cat, Dog 클래스의 공통되는 함수와 특수한 함수들을 정하여 선언한다.

포인터를 사용해 Cat 객체를 만들어 speak()함수를 실행한다고하면

으로 실행할 수 있다.

객체의 상태에 확인해보면

Animal 객체에서 나타나는 가상테이블 포인터, Animal data에 각각의 data를 포함한 형태를 띤다.

Cat * catPtr = new Cat();은 catPtr 포인터로 Cat 객체를 가리키고 있다.

그러므로 Cat포인터는 Cat 객체에 대한 모든 scope를 가지고있다.
이 때 upcast가 가능한데

Cat 포인터가 아닌 animalPtr 포인터로 선언할지라도 speak()함수는 meow를 출력한다.

그 이유는 animal포인터가 여전히 Cat 객체를 가리키고 있고 Cat객체의 가상테이블 포인터가 Cat 가상테이블을 가리키고 있기 때문이다.
하지만 knead()함수를 실행하려하면 에러가 나는데 이는 Animal 포인터는 Animal에 대한 정보만 접근이 가능하기 때문에 Cat의 고유한 함수인 knead()에는 접근이 불가능하다.

이를 하고 싶으면 downcast를 해줘야하는데

이렇게 catPtr 포인터를 만들어 implicit downcast하게 되면 컴파일 에러가 난다.
c++에서 허용하지 않기 때문인데

그 이유는

다음과 같이 Animal 포인터를 만들고 Cat 포인터로 downcast하여 knead()함수를 실행하면

원래 Cat 객체에서 knead()함수가 있는 간격만큼 이동하여 메모리를 사용하여 프로그램이 정지하거나 오작동할 수 있기 때문이다.

그래서 안전성을 위해 dynamic cast를 사용할 수 있다.


dynamic cast는 cast하고 싶은 객체의 타입과 포인터의 타입이 다르면 nullptr를 반환한다
따라서 위와 같이 예외처리가 가능해진다.

이렇게 런타임시간에 타입이 일치하는 지 확인 할 수 있는 이유는
각 가상테이블마다 타입에 맞는 타입 정보가 저장되어있기 때문이다.

그래서 타입 정보와 downcast한 포인터가 일치하는지 확인한다.

0개의 댓글