공부/c++

c++ 형변환 연산자(static_cast, const_cast, reinterpret_cast, dynamic_cast)

장금선 2021. 5. 25. 00:13
double d = 3.14;
int i = (int)d;

이런 형변환은 C스타일 형변환 혹은 명시적 형변환 이라고 부른다.

암시적 형변환이 불가능하다는 뜻을 담고 있고, 형변환의 의도를 구별해내기 힘들다는 문제점이 있다.

 

그래서 C++에서는 4가지 형변환연산자를 제공한다.

 


static_cast

정적 형변환. 가장 일반적인 형태의 형변환이다.

A타입에서 B타입으로 암시적인 형변환이 가능하다면 static_cast를 사용해 형변환 할 수 있다.

기본 자료형 데이터 간 형변환과 클래스 상속관계에서의 형변환만 허용한다.

double d = 3.14;
int i = static_cast<int>(d);

const_cast

const속성이나 volatile 속성을 제거할 때 사용.

*volatile : 가끔 컴파일러가 변수를 상수로 만들어버리는 작업을 수행. volatile로 그 작업에서 제외시킨다. 멀티스레드에서 사용할 수 있음.

const int value = 100;
int i = const_cast<int>(value);

reinterpret_cast

포인터/참조 관련된 형변환. 전혀 상관없는 자료형으로의 형변환에 사용된다.

int num = 0x01020304;
char* ptr = reinterpret_cast<char*>(&num);
if(ptr[0] == '\x04')
	std::cout<< "little-endian";	// 리틀엔디안. [04][03][02][01]
else
	std::cout<< "big-endian";	// 빅엔디안. [01][02][03][04]

 


dynamic_cast

서로 상속관계에 있고 가상함수를 지니는 클래스간 형변환 할때 사용된다.

형변환과 동시에 이 형변환이 안전한지까지 검사해준다.

-> 형변환 했을 때 가리킬 수 없는 타입으로 형변환 할 경우 nullptr 반환

#include <iostream>

class Animal {

public:
	virtual void move() const {
		std::cout << "Animal - move" << std::endl;
	}
};

class Dog : public Animal {

public:
	virtual void move() const override{
		std::cout << "Dog - move" << std::endl;
	}
};

int main()
{
	// 컴파일 OK
	Animal* animal1 = new Dog();
	Dog* dog1 = static_cast<Dog*>(animal1);
	dog1->move();

	// 컴파일은 되지만 왜 이런짓을?
	Animal* animal2 = new Animal();
	Dog* dog2 = static_cast<Dog*>(animal2);
	dog2->move();

	// 컴파일 OK
	Dog* dog3 = dynamic_cast<Dog*>(animal1);
	dog3->move();

	// dog4는 nullptr을 가르킴
	Dog* dog4 = dynamic_cast<Dog*>(animal2);
	if(dog4)
		dog4->move();
}

- 기본 자료형간 형변환은 static_cast

- 상속관계에서 안정적인 형변환을 원한다면 dynamic_cast

- 상속관계에서 때로는 형변환을 강제해야 하는 상황이라면 static_cast

- 포인터/참조 타입에 상관없이 무조건 형변환을 강제하고 싶다면 reinterpret_cast

- const 성향을 없애고 싶다면 const_cast