C++의 형변환 연산자
C++은 무조건적인 형변환을 해주는 C스타일의 형변환보다 안전하게 형변환하기 위해 4개의 형 변환 연산자를 제공한다,
dynamic_cast
static_cast
const_cast
reinterpret_cast
위 형 변환 연산자를 사용하면 프로그래머는 자신이 의도한 바를 명확히 표시할 수 있다.
dynamic_cast : 상속관계에서의 안전한 형변환
dynamic_cast<T>(expr)
<>사이에 변환하고자하는 자료형의 이름을 두되 , 객체의 포인터 또는 참조형이 와야하며 () 사이에는 변환의 대상이 와야한다. 적절한 변환일경우 형변환된 데이터를 반환하지만 요구한 형 변환이 적절하지 않은 경우에는 컴파일 에러가 발생한다.
dynamic_cast 변환은 상속관계에 놓여있는 두 클래스 사이에서 유도클래스의 포인터 및 참조형 데이터를 기초형 포인터 및 참조형 데이터로 형변환 하는경우 변환을 허가한다. 즉 , dynamic_cast 연산자를 사용했다는것은 상속관계에 있는 유도클래스의 포인터 및 참조형 데이터를 기초 클래스의 포인터 및 참조형 데이터로 형 변환하겠다는 뜻이다.
class Truck : Car 일경우
Truck * ptruck = new Truck() ;
Car * pcar = dynamic_cast<Car*>(ptruck);
static 변환 : A타입에서 B 타입으로
static_cast<T>(expr)
static_cast를 사용하면 유도클래스의 포인터 및 차몾형 데이터를 기초클래스의 포인터 및 참조형 데이터로 뿐만아니라 , 기초 클래스의 포인터 및 참조형 데이터도 유도클래스의 포인터 및 참조형 데이터로 아무런 조건없이 형변환해준다. ( dynamic_cast 보다 넓은 범위로 형변환 , 연산속도 빠름 )
Car * pcar1 = new Truck();
Truck *ptruck1 = static_cast<Truck*>(pcar1); // 올바른 사용
Car * pcar2 = new Car();
Truck * ptruck1 = static_cast<Truck*>(pcar2);// 잘못된사용 but 컴파일 가능 -> 책임은 프로그래머가 져야함
static_cast 연산자는 dynamic_cast 보다 많은 형 변환을 허용하기때문에 , 이에따른 책임은 프로그래머가 져야하고 , 따라서 dynamic_cast 연산자를 사용할 수 있는 경우에는 이를 사용하여 안전성을 높여야한다.
static_cast 연산자는 기본 자료형 데이터간의 형변환에도 사용된다.
즉 , static_cast 연산자는 기본자료형간의 형변환과 클래스의 상속관계에서의 형 변환만 허용한다.
double result = static_cast<double>(20)/3;
const_cast : const의 성향을 삭제한다
const_cast<T>(expr)
const_cast형 변환연산은 함수의 인자전달시 const 선언으로인한 형의 불일치가 발생하여 인자의 전달이 불가능할때 , 유용하게 사용된다.
void ShowString(char * str)
{
cout<<str <<endl;
}
int main (void)
{
const char * name = "홍길동";
ShowString(const_cast<char*>(name));
return 0;
}
reinterpret_cast : 상관없는 자료형으로의 형 변환
reiinterpret_cast 연산자는 전혀 상관없는 자료형으로의 형 변환에 사용된다. 즉 , 포인터를 대상으로하는 , 그리고 포인터와 관련이 있는 모든 유형의 형 변환을 허용한다.
int num =0x010203;
char * ptr = reinterpret_cast<char*>(&num);
dynamic_cast 두번째 이야기 : polymorphic 클래스 기반의 형 변환
dynamic_cast도 기초 클래스의 포인터 및 참조형 데이터를 유도 클래스의 포인터 및 참조형 데이터로의 형 변환을 허용하는경우가 있는데 , 이때는 기초클래스가 Polymorphic 클래스인 경우이다 . Polymorophic 클래스란 하나이상의 가상함수를 지니는 클래스를 뜻한다( 추상클래스 ) ( virtual 포함 )
Sosimple클래스가 추상클래스라고할때
SoSimple * simPtr = new SoComplex;
SoComplex * comPtr = dynamic_cast<SoComplex* >(simPtr);
이때 , dynamic_cast와 static_cast와의 차이는 dynamic_cast의 경우
SoSimple * simPtr = new SoSimple
SoComplex * comPtr = dynamic_cast<SoComplex *>(simPtr);
comPtr이 simPtr 을 가리킬 수 없을경우 , 형변환의 결과로 NULL을 반환한다는 것이다 . ( comPtr에 NULL값이 저장된다 ) 이때, if문을 이용해 형변환 성공 유무를 판단할 수 있다.
bad_cast 예외
bad_cast 예외는 dynamic_cast 연산자를 이용한 형변환 과정에서 발생할 수 있는 예외이다.
try
{
SoSimple simObj;
SoSimple& ref = simObj;
SoComplex& comRef = dynamic_cast<SoComplex&>(ref);
}
catch(bad_cast expt)
{
cout<<expt.what()<<endl;
}
참조자 대상으로는 NULL을 반환할 수 없기때문에 , 이러한 상황에서는 bad_cast 예외가 발생하며 , 이를 catch 문으로 잡아서 예외처리를 해야한다.
'C++언어 > 열혈C++' 카테고리의 다른 글
C++ : Chapter -14 예외처리 try catch (0) | 2018.06.23 |
---|---|
C++ : Chapter -13 템플릿 PART2 (0) | 2018.06.19 |
C++ : Chapter -12 템플릿 PART1 (0) | 2018.06.19 |
C++ : Chapter -11 연산자 오버로딩 PART2 (0) | 2018.06.17 |
C++ : Chapter -10 연산자 오버로딩 PART1 (0) | 2018.06.13 |