Create TOC

2002년 5월 14일

C++/Type Casting

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 이 발생된다.

아래와 같은 경우에는 사용할 수 없다.

  1. 가상 함수가 없는 경우
  2. 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 작성시 사용을 피하는 것이 좋다.