dynamic_cast, static_cast, reinterpret_cast, const_cast에 대해 다루는 글.
dynamic_cast <new_type> (expression)
reinterpret_cast <new_type> (expression)
static_cast <new_type> (expression)
const_cast <new_type> (expression)
: 캐스팅할 타입이 compatible type일 경우 컴파일러가 자동으로 캐스팅한다.
short a=2000;
int b;
b=a;
: 포인터와 그에 관련된 클래스 사이에서 수행되는 conversion이다.
1 class B {};
2
3 class D : public B {};
4
5 void f(B* b, D* d) {
6 D* d2 = static_cast<D*>(b);
7
8 B* b2 = static_cast<B*>(d);
9 }
코드 출처
위 같은 경우 D클래스는 B 클래스를 상속받았고 다운캐스팅과 업캐스팅을 수행한다.
line 6 처럼 static_cast를 통해 다운캐스팅하는 경우 에러는 발생하지 않는다. 하지만 B클래스는 없지만 D클래스가 갖는 멤버를 호출하는 경우 문제가 생길 수 있다.
class B {
public:
virtual void Test(){}
};
class D : public B {};
void f(B* pb) {
D* pd1 = dynamic_cast<D*>(pb);
D* pd2 = static_cast<D*>(pb);
}
pb는
1. 처음부터 B클래스의 인스턴스로 생성된 경우
2. 자식인 D클래스의 인스턴스였지만 B 타입으로 업캐스팅된 경우
둘 중 한 경우에 속할 것이다.
만약 1인 경우 dynamic_cast는 bad_cast로 판단하고 0을 리턴할 것이고 2인 경우 정상적으로 캐스팅을 수행할 것이다.
static_cast면 두 경우의 차이를 구분하지못하고 캐스팅을 수행할 것이다.
: 포인터와 래퍼런스를 클래스로 변환한다.
: 포인터 타입을 다른 포인터 타입으로 변환한다(관련없는 포인터라도 변환한다).
모든 포인터 변환이 가능하지만 가르키는 content나 포인터 타입은 체크하지 않는다.
Data *test = new Data(34, "qwe");
char a = reinterpret_cast<char>(test);
test = reinterpret_cast<Data *>(a);
Data 객체를 가르키는 포인터를 char형으로 변환을 시도한 코드이다.
main.cpp:47:12: error: cast from pointer to
smaller type 'char' loses information
...char a = reinterpret_cast<char>(test);
위처럼 정보를 잃을 수 있다는 컴파일 에러가 발생한다.
: 가르키는 포인터의 const속성을 설정하거나 제거한다.
example
void print (char * str)
{
cout << str << '\n';
}
int main () {
const char * c = "sample text";
print(c);
return 0;
}
output>>
main.c:11:3: error: no matching function for
call to 'print'
print(c);
^~~~~
main.c:4:6: note: candidate function not viable:
1st argument ('const char *') would lose
const qualifier
void print (char * str)
const가 없다며 매칭되는 함수가 없어 컴파일 에러가 발생한다.
void print (char * str)
{
cout << str << '\n';
}
int main () {
const char * c = "sample text";
print ( const_cast<char *> (c) );
return 0;
}
output>>
sample text