캐스팅 연산자 static_cast C++

오늘부터 2,3회에 걸쳐 C++의 캐스팅 연산자를 정리해 보려 합니다. 사실 캐스팅 연산자는 C언어에서 사용하는 ( ) 연산자가 있습니다. 단순하게 변환하고자 하는 변수가 있다면 " (type)변수 " 이렇게 써주면 되죠. 누구나 아실거라 생각합니다.  

C언어의 캐스팅은 이렇게 단순하고 캐스팅도 아주 자~알 됩니다. 그럼에도 C++에서는 캐스팅 연산자를 여러개로 준비해 놨습니다. 

그럼 왜 캐스팅 연산자를 여러개로 나눠나서 골치아프게해~! 하고 그냥 C에서 쓰던데로 쓰실 수도 있겠습니다. 하지만 C언어에서 사용하던 캐스팅 방법은 안정성이 없습니다. 

예를 들어 보죠.


C언어 스타일의 캐스팅 연산

int x = 3;
int * p = &x;
printf("%c\n", (char)x);
printf("%d\n", (char*)x);
printf("%d\n", (int*)x);
printf("%f\n", (double*)x);
printf("%d\n", (int)p);
printf("%c\n", (char)p);

위 코드는 큰 의미는 없습니다. 단지 기본타입이 포인터 타입으로 캐스팅 되거나 포인터가 기본타입으로 캐스팅될 수도 있다는 점에 주목하시면 됩니다. 
이런 기본 타입과 포인터 타입간에 변환은 일반적으로 의미가 없습니다. 그럼에도 위와 같이 포인터를 사용하다 보면은 실수할 수가 있겠네요. 그리고 그 실수가 쉽게 발견되지 않을 수도 있구요. 따라서 안정적이지 못합니다.

static_cast<type>(obj

가장 기본적인 캐스팅 연산자입니다. obj의 타입을 type으로 바꿉니다. 이 연산자의 특징은 다음과 같습니다. 

  • 우선 일반적으로 앞서 예와 같이 포인터와 기본타입간에 변환이 안됩니다. 의미없죠. 즉, 논리적으로 가능한 경우만 변환이 됩니다. 
char * str = "BAC";
(int)str;            //OK!

static_cast<int>(str);    //Error

int x = 3;
int *p = &x
static_cast<int>(p);    //Error
static_cast<int*>(x);    //Error
따라서 목적에 맞는 안전한 캐스팅을 할 수 있습니다.
  • 상수를 상수가 아닌 타입으로 변환하는 것은 static_cast로 가능하지만 상수에 대한 포인터나 참조인 경우에는 가능하지 않습니다. 이 경우에는 const_cast를 사용해야 합니다.
const int i = 10;
static_cast<int>(i);    //OK!

const int * pi = &i;
static_cast<int *>(pi);    //Error

const_cast<int *>(pi);    //OK!

참고 : const_cast는 상수 지시 포인터의 상수성(만)을 변경하는데 특화된 포인터

단 포인터인 경우에는 포인터로 참조인 경우에는 참조로 캐스팅 해야합니다. 왜냐면 const_cast는 상수의 성질만 바꿀 수 있기 때문입니다.


또한 포인터 타입간의 변환은 절대 안됩니다. 단 가능한 경우는 다음과 같습니다.
  • 클래스의 상속 관계에서는 포인터 간에 캐스팅이 가능합니다. 즉 부모객체에 대한 포인터 타입과 자식 객체에 대한 포인터 타입간에 캐스팅입니다.(참조형 간에도 가능 합니다. 단, 객체 자체타입으로 변환은 안됩니다.) 하지만 이런 경우에는 안정성의 이유로 static_cast를 사용하지 않고 dynamic_cast를 사용합니다. 이 내용은 dynamic_cast를 다룰 때 다시 언급되므로 여기서는 그냥 넘어가도록 하겠습니다.
이렇게 정리해 보고 나니 처음 배우는 분들은 익숙해 지기전 까진 복잡하게 느껴질 수 있게다고 생각되네요.

'프로그래밍 > cpp' 카테고리의 다른 글

extern, static 지정자  (0) 2017.04.06
구조체 멤버 맞춤(struct member alignment) C++  (0) 2017.03.26
캐스팅 연산자 static_cast C++  (0) 2017.03.24
전위 연산, 후위 연산자 c++  (1) 2017.03.20
연산자 오버로딩 정리 c++  (0) 2017.03.19
우측값 참조 [C++11]  (0) 2015.10.24
이 댓글을 비밀 댓글로