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 |