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 문으로 잡아서 예외처리를 해야한다.

+ Recent posts