[C++] cast

junpkim·2022년 7월 29일
0

C++에는 casting을 위한 연산자 4가지를 제공한다.
static_cast, const_cast, dynamic_cast, reinterpret_cast 인데 각자의 역할이 모두 다르다.

static_cast

static_cast 는 가장 일반적인 형변환 형식이다. 논리적으로 변환 가능한 타입을 변환해준다. 예를들어 float형을 int로 변환한단거나 하는

float a = 10.123
int b = static_cast<int>(a);

이런식으로 사용하면 된다.

const_cast

cosnt_cast는 const 형식의 변수에서 const를 제거하는데 사용된다.
그렇다고 const형 변수의 값을 변환할 수 있는건 아니고,

void f(int n);

int main()
{
	const int a = 10;
    f(*(const_cast<int *>(&a));
}

위와 같이 const형이 아닌 매개변수를 받는 함수의 매개변수로 const형 변수를 넘겨주려고 할 때나 사용된다.
그리고 형 변환은 포인터형으로만 변경할 수 있다.

하지만 const_cast에는 큰 취약점이 존재하는데,

const int a = 10;
int *b = const_cast<int *>(&a);
*b = 20;
cout << a << " " << *b << endl;
cout << &a << " " << b << endl;

위 코드를 실행해보면
이와 같이 출력된다.
b는 a를 가리키는 포인터이고, 해당 주소에 있는 값을 변경해주었으나 a의 값은 변경되지 않고 출력이 된다.
그리고 또 정작

const int *c = &a;

코드를 추가해서 실행해보면 20이 출력된다.

그러니 const 변수의 주소에 접근해서 값을 변경하는데 사용하지는 말자.

dynamic_cast

dynamic_cast 는 업캐스팅 후 안정적인 다운캐스팅을 하는데 사용된다.
예를 들어 Base를 상속받은 클래스 A, B, C가 존재한다고 하자.
그리고 Base 형 변수 b에 A, B, C 셋 중 하나의 생성자가 랜덤하게 실행된다고 할 때, 이 변수의 원래 타입을 찾는데 사용될 수 있다.
사용방법은 다음과 같다.

	if (dynamic_cast<A*>(b))
		std::cout << "A" << std::endl;
	else if (dynamic_cast<B*>(b))
		std::cout << "B" << std::endl;
	else if (dynamic_cast<C*>(b))
		std::cout << "C" << std::endl;

reinterpret_cast

reinterpret_cast 는 일반적으로 허용되지 않는 캐스팅에 사용된다. 포인터를 정수로, 정수를 포인터로 혹은 포인터를 다른 타입의 포인터로 바꾸는데 사용할 수 있다.
일반적으로 포인터형 변수를 다른 타입(특히 그보다 작은 크기의 자료형)으로 변환할 수 없다. 예를들어 int형 포인터 변수는 4byte를 차지하지만 char형 변수는 1byte를 차지한다.

int a = 123;
int *b = &a;
char c = *(reinterpret_cast<char *>(b));

이런식으로.
결국 형 변환을 해줄 때 char형 포인터 변수로 형변환 해준 것의 값을 char에 넣은거 아니냐고 할 수도 있지만, static_cast로는 불가능한 변환이다.

0개의 댓글