14. 프렌드, 예외, 기타사항(6) - 데이터형 변환 연산자(const_cast, static_cast, reinterpret_cast)

WanJu Kim·2022년 12월 18일
0

C++

목록 보기
64/81

일반적으로 데이터형 변환은 변환하고 싶은 변수 앞에 '(데이터형)변수' 뭐 이런 식으로 쓴다. 근데 이게 좀... 불안정하다고 한다. 그래서 이걸 강화하고자 4개의 데이터형 변환을 만들었다.

dynamic_cast
const_cast
static_cast
reinterpret_cast

dynamic_cast는 저번에 배웠고, const_cast부터 알아보자.

const_cast 연산자

const_cast 연산자는 어떤 값을 const나 volatile로, 또는 그 반대로 변환할 수 있다. 사용 방법은 dynamic_cast와 비슷하다.

High bar;
const High * pbar = &bar;

High * pb = const_cast<High *>(pbar)	// 맞다.
const Low * pl = const_cast<const Low*>(pbar);	// 틀리다.

첫 번재는 const를 const가 아닌 포인터로 바꾸기 때문에 가능하다. 두 번째는 const를 const로 변환한다고 해서 틀렸다.

이 연산자는 왜 필요하나? const로 정의한 상수를 가끔씩 바꾸어야 할 때가 있기 때문이다. 근데 이거 일반 데이터형 변환도 가능하다. 그럼 왜 굳이 const_cast를 써야 하냐고? 일반 데이터형 변환은 데이터형도 동시에 바꿀 수 있어서 실수를 저지를 수 있기 때문이다. (잘 쓰면 좋은 거 아닌가? ㅋㅋ)

High bar;
const High * pbar = &bar;

High & pb = (High*)(pbar);	// 맞다.
Low * pl = (Low*)(pbar);	// 데이터형 변환도 같이 된다.

static_cast 연산자

static_cast는 일반적인 데이터형 변환과 비슷하다. 대신 변환이 안 될 때는 에러를 호출한다. 예를 들어 High가 Low의 기초 클래스이고, Pond는 이 별개의 클래스라고 가정하자.

High bar;
Low blow;

High * pb = static_cast<High*>(&blow);	// 유효한 업캐스팅.
Low * pl = static_cast<Low*>(&bar);		// 유효한 다운캐스팅.
Pond * pmer = static_cast<Pond*>(&blow)	// 에러 호출.

첫 번째는 업캐스팅이라 당연히 된다. 두 번째는 다운캐스팅인데 형변환 하면 되나 보다 ㄷㄷ. 형변환이 없으면 당연히 안 된다. 세 번째는 관련이 없어서 에러를 호출한다.

이와 비슷하게 double형을 int형으로 바꾼다던지, 열거값을 정수형으로 바꾼다던지가 가능하다.

reinterpret_cast 연산자

reinterpret_cast 연산자는 위험한 데이터형 변환을 하기 위해 쓰인다.

struct dat { short a; short b; };
	
long value = 0xA224B118;
dat* pd = reinterpret_cast<dat*>(&value);
cout << pd->a;	// value의 처음 2바이트를 출력한다.

굉장히 난해하다. 근데 이 연산자도 불가능할 때가 있다. 예를 들어 포인터형을 포인터형을 저장할 수 있는 큰 정수형으로 캐스팅할 수 있지만, 반대는 안 된다. 또 함수 포인터를 데이터 포인터로, 그 반대도 안 된다. 언제 사용하게 되는지 궁금하다.

profile
Question, Think, Select

0개의 댓글