C++에서는 C와 달리 casting 에 관련된 keyword가 다음 4가지가 존재하며, 각각 의미가 다르다. C++ 에서는 기존의 C-style casting 보다는 추가된 keyword를 사용한 casting을 권장한다.
static_cast
C-style casting과 동일하다. 따라서 C-style casting 에서 발생하는 모든 제약이 동일하게 적용된다.
이런 C 코드는
int firstNumber, secondNumber;
double result = ( ( double ) firstNumber ) / secondNumber ;
이런 C++ 코드로 바꿀 수 있다.
int firstNumber, secondNumber;
double result = static_cast <double> (firstNumber) / secondNumber ;
const_cast
const_cast는 표현식의 상수성(const)과 휘발성(violate)을 제거하는데 사용한다. 아래 예를 보면
class Root;
class Leaf : public Root;
Leaf * pLeaf;
Leaf Leaf;
const Leaf & cLeaf = Leaf;
Root * pRoot = new Leaf ;
pLeaf = &cLeaf; // error: 형이 다르다.
pLeaf = const_cast <Leaf *>(&cLeaf); // ok.
pLeaf = (Leaf *) &cLeaf; // ok. C-style casting.
pLeaf = pRoot; // error. 형이 다르다.
pLeaf = const_cast <Leaf *> (pRoot); // error
dynamic_cast
상속 관계를 가진 경우에만 사용할 수 있다. 즉, 기본 class object 의 포인터(pointer)나 참조형(reference)을 파생(derived) class 또는 형제(sibling) class 타입으로 변환할 때 사용한다. 실패했을때는 NULL 리턴(포인터 변환시) 또는 exception 이 발생된다.
아래와 같은 경우에는 사용할 수 없다.
- 가상 함수가 없는 경우
- const_cast와 같이 상수성(const)을 제거하려는 경우.
class Root;
class Leaf : public Root;
Leaf * pLeaf;
Root * pRoot = new Leaf ;
Leaf Leaf;
const Leaf & cLeaf = Leaf;
Leaf & rLeaf = dynamic_cast <Leaf &> (*pRoot); // ok.
pLeaf = pRoot; // error. 형이 다르다.
pLeaf = dynamic_cast <Leaf *> (pRoot); // ok.
pLeaf = dynamic_cast <Leaf *> (&cLeaf); // error. const를 제거할 수 없다.
reinterpret_cast
포인터(pointer) 끼리의 형변환, 포인터를 정수형으로 형변환 그리고 정수형을 포인터로 형변환 할 때 사용된다. 서로 연관성이 없는 포인터(pointer)라고 해도 형변환이 가능하기 때문에 되도록이면 쓰지 않는 것이 좋다. casting 결과도 compiler 에 의존적이기 때문에 portable한 code 작성시 사용을 피하는 것이 좋다.