티스토리 뷰

C++에서 지원하는 타입 캐스팅은 크게 4가지로 아래와 같이 분류되는데, 각 캐스팅마다 특징이 조금씩(응?) 다 다르다. 의외로 오랫동안 프로그래밍을 해 온 사람도 그 차이에 대해 명확하게 설명하지 못하는 경우가 많고 상황에 따라 적당히 경험적으로 시행착오를 통해 쓰는 경우가 있는데 그래서는 안될 것 같아 정리를 해 보았으니 이에 대해 한번 살펴보기로 하자.


static_cast

static_cast is the first cast you should attempt to use. It does things like implicit conversions between types (such as int to float, or pointer to void*), and it can also call explicit conversion functions (or implicit ones). In many cases, explicitly stating static_cast isn't necessary, but it's important to note that the T(something) syntax is equivalent to (T)something and should be avoided (more on that later). A T(something, something_else) is safe, however, and guaranteed to call the constructor.

static_cast can also cast through inheritance hierarchies. It is unnecessary when casting upwards (towards a base class), but when casting downwards it can be used as long as it doesn't cast through virtualinheritance. It does not do checking, however, and it is undefined behavior to static_cast down a hierarchy to a type that isn't actually the type of the object.


실수형, 정수형, 열거형등 기본적인 형 사이의 변환을 할 때 사용된다. 

상속관계 클래스 계층 간의 변환 가능

RTTI 지원 없이 사용 가능

다중 상속에서 기본 클래스간 변환은 불가함

void pointer를 다른 타입으로 변환 가능

서로 다른 타입간에는 변환 불가



const_cast

const_cast can be used to remove or add const to a variable; no other C++ cast is capable of this (not evenreinterpret_cast). It is important to note that using it is only undefined if the orginial variable is const; if you use it to take the const of a reference to something that wasn't declared with const, it is safe. This can be useful when overloading member functions based on const, for instance. It can also be used to add const to an object, such as to call a member function overload.

const_cast also works similarly on volatile, though that's less common.


const_cast는 포인터 또는 참조형의 상수성을 제거하는데 사용된다.

예제>

const int * pConstInt = new int(10);

int* pInt = const_cast<int *>(pConstInt);

*pInt = 100;

이와 같이 const 선언된 변수의 상수성을 제거하는 용도로 사용이 됩니다.



dynamic_cast

dynamic_cast is almost exclusively used for handling polymorphism. You can cast a pointer or reference to any polymorphic type to any other class type (a polymorphic type has at least one virtual function, declared or inherited). You don't have to use it to cast downwards, you can cast sideways or even up another chain. Thedynamic_cast will seek out the desired object and return it if possible. If it can't, it will return NULL in the case of a pointer, or throw std::bad_cast in the case of a reference.


상속관계 안에서 포인터나 참조자의 타입을 기본 클래스에서 파생 클래스로의 다운 캐스팅과 다중 상속에서 기본 클래스간의 안전한 타입 캐스팅에 사용된다. 거의 대부분 다중상속에서만 사용된다고 보면 된다.

(Tip) 아래 예와 같이 객체가 위치한 시작 포인터를 찾는데도 사용이 가능함.

ex> void* pObj = dynamic_cast<void *>(pObject)

런타임에 타입 검사를 하기 때문에 컴파일러의 RTTI 옵션이 켜진 상태에서만 사용 가능하다. 



reinterpret_cast

reinterpret_cast is the most dangerous cast, and should be used very sparingly. It turns one type directly into another - such as casting the value from one pointer to another, or storing a pointer in an int, or all sorts of other nasty things. Largely, the only guarantee you get with reinterpret_cast is that if you cast the result back to the original type, you will get the same value. Other than that, you're on your own. reinterpret_castcannot do all sorts of conversions; in fact it is relatively limited. It should almost never be used (even interfacing with C code using void* can be done with static_cast).


reinterpret_cast는 C cast 다음으로 위험한 캐스팅이다. 캐스팅 대상을 캐스팅 타입으로 비트 단위로 쪼개서 재해석한다고 보면 된다. 결과는 때론 컴파일러마다 다르기도 하여 위험한 방식이며 책임은 모두 프로그래머의 몫이다. 최후의 수단이라고 생각하면 된다. 



C casts

A C cast ((type)object or type(object)) is defined as the first of the following which succeeds:

  • const_cast
  • static_cast
  • static_cast, then const_cast
  • reinterpret_cast
  • reinterpret_cast, then const_cast

It can therefore be used as a replacement for other casts in some instances, but can be extremely dangerous because of the ability to devolve into a static_cast, and the latter should be preferred when explicit casting is needed, unless you are sure static_cast will succeed or reinterpret_cast will fail. Even then, consider the longer, more explicit option.


가급적 이제는 사용하지 말길 권하는 전통적인 C Style 캐스팅으로 설명은 생략함.

저작자 표시
신고
댓글
댓글쓰기 폼