c 언어에서 사용하는 타입 캐스팅 방식을 c++에서 사용할 수 있지만 타입 캐스팅을 위한 연산자가 따로 제공된다. (static_cast, dynamic_cast, reinterpret_cast, const_cast)
기존에 사용하는 c 스타일의 방식은 의도를 파악하기 어렵고, 가차없이 진행되지만 c++ 스타일의 방식으로 조금더 안정적인 코드를 작성할 수 있다.
classParent{private:intx;public:Parent(intx):x(x){}voidprint_x(void){std::cout<<"x: "<<x<<std::endl;}};classChild:publicParent{private:inty;public:Child(intx,inty):Parent(x),y(y){}voidprint_point(void){Parent::print_x();std::cout<<"y: "<<y<<std::endl;}};intmain(void){Parent*p1=newChild(10,20);Child*c1=static_cast<Child*>(p1);c1->print_point();Parent*p2=newParent(10);Child*c2=static_cast<Child*>(p2);c2->print_point();}// c2->y 에는 임의의 값이 들어간다.
Errors
1
2
3
4
5
6
7
8
9
doubled=3.14;double*ptr=&d;int*x=static_cast<int*>(d);std::cout<<x<<std::endl;/*
<컴파일 에러>
error: cannot cast from type 'double' to pointer type 'int *'
*/
1
2
3
4
5
6
7
8
9
doubled=3.14;double*ptr=&d;int*x=static_cast<int*>(ptr);std::cout<<x<<std::endl;/*
<컴파일 에러>
error: static_cast from 'double *' to 'int *' is not allowed
*/
dynamic_cast 연산자
상속 관계에서 static_cast보다 안정적으로 타입 캐스팅을 처리한다.
자식 -> 부모 변환에서 safe downcasting이 가능하다.
dynamic_cast는 런타임에서 안정성 검사를 진행한다.
컴파일 시점에는 변환하려는 클래스가 다향성 클래스인지 검사한다.
런타임 시간에 해당 타입이 다운 캐스팅이 가능한지 검사하기 때문에 런타임 비용이 조금 높다.
성공할 경우 new_type의 value를 반환한다.
실패한 경우
new_type이 포인터라면 null pointer
new_type이 참조라면 bad_cast (exception)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
intmain(void){Parent*p1=newChild(10,20);Child*c1=dynamic_cast<Child*>(p1);// 컴파일 에러: error: 'Parent' is not polymorphicc1->print_point();Parent*p2=newParent(10);Child*c2=dynamic_cast<Child*>(p2);// 컴파일 에러: error: 'Parent' is not polymorphicc2->print_point();}
dynamic_cast는 가상 함수를 가진 다향성 클래스에 한해서는 부모 -> 자식 타입 캐스팅을 허용한다.
1
2
Parent*p1=newChild(10,20);Child*c1=dynamic_cast<Child*>(p1);// error: 'Parent' is not polymorphic
1
2
3
4
5
6
classParent{// ...virtualvoidprint_x(void)// 가상 함수};
1
2
Parent*p1=newChild(10,20);Child*c1=dynamic_cast<Child*>(p1);// 컴파일 성공
부모 객체를 자식 클래스로 변환하면 컴파일을 성공하지만 null pointer가 반환된다.
intmain(void){inti=0;constint*ptr=&i;double*d=const_cast<double*>(ptr);std::cout<<d<<std::endl;return(0);}/*
< 컴파일 에러 >
error: const_cast from 'const int *' to 'double *' is not allowed
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
intmain(void){inti=0;constint*ptr=&i;double*d=const_cast<double>(ptr);std::cout<<d<<std::endl;return(0);}/*
< 컴파일 에러 >
error: const_cast to 'double', which is not a reference,
pointer-to-object, or pointer-to-data-member
*/