728x90
class Parent
{
public:
	virtual ~Parent() { }
};

class Child : public Parent
{
public:
	int _number = 10;
};

class Child2 : public Parent
{
public:
};
 
  • static_cast

기본적인 자료형 변환, 상속구조에서의 캐스팅에 대한 작업에 사용이 가능하지만 이러한 캐스팅에 안정성을 확인하는 것은 프로그래머에게 맡긴다. 즉, 상식적으로 안전한 캐스팅에 사용되는 문법이다.

// static cast
int a = 100;
double b = static_cast<double>(a);
Child* child = new Child();
Parent* parent = static_cast<Parent*>(child);
Parent* parent2 = new Parent();
Child* child2 = static_cast<Child*>(parent2); // 통과 but 이상... 안전은 프로그래머에게!
cout << child2->_number << endl; // 쓰레기 값
 
  • dynamic_cast

상속구조에서의 안정성을 체크한 후 캐스팅한다. RTTI(Run Time Type Information)를 활용하여 가상함수 테이블을 참고하고 어떤 클래스를 상속받았는지 추적하여 안정성을 더한 캐스팅기법이다. 만약 잘못된 캐스팅을 하였을 경우 nullptr을 반환하게 된다. static_cast에 비해 안정성은 높지만 성능은 떨어진다고 할 수 있다.

// dynamic cast 
// RTTI를 활용하여 가상함수 테이블을 참고
Parent* parent3 = new Child();
Child* child3 = dynamic_cast<Child*>(parent3);
cout << child3->_number << endl;
Parent* parent4 = new Child2();
Child* child4 = dynamic_cast<Child*>(parent4); // 원본이 Child2이기 때문에 nullptr
if (child4 != nullptr)
	cout << child4->_number << endl;
 
  • const_cast

const형식의 타입은 비 const형식으로 비 const형식은 const형식으로 변환해주는 캐스팅이다.

void Print(char* str)
{
	cout << str;
}

int main()
{
  Print(const_cast<char*>("LeafC"));
}
 
  • reinterpret_cast

거의 강제로 캐스팅을 하는 경우 사용하는 방법. 전혀 관계 없는 포인터 끼리의 형변환을 가능하게 해준다. 주로 메모리 구조를 확실하게 알고 데이터를 추출할 때 사용하는 것 같다.

struct Data
{
	int a = 1;
	int b = 2;
};

struct Information
{
	Data data;
	int c = 3;
	int d = 4;
};

int main()
{
	Information* info = new Information();
	info->data.a = 10;
	info->data.b = 20;
	Data& data = info->data; // 데이터 추출
	// 여기저기서 막~~ 건드리다 보니 원래 데이터였던 info의 존재를 잊어버렸다고 가정
	Information* info2 = reinterpret_cast<Information*>(&data); // 원본 info 추출 가능
}
 

 

 

728x90

'C++ > C++ 기본' 카테고리의 다른 글

생성자 (Constructor)  (1) 2023.05.16
템플릿 기초  (0) 2023.05.12
함수 포인터  (0) 2023.05.12
얕은 복사와 깊은 복사  (0) 2023.05.12

+ Recent posts