개요
C에서는 캐스팅이 단순히 변수 앞에 (타입)을 붙여 컴파일러가 해당 타입에 대해 에러를 내지 않게 하는 것에 그쳤다.
이러한 방법은 너무 강력하기 때문에 C++에서는 세분화한 캐스팅 방법을 제공한다.
1. static_cast
2. dynamic_cast
3. const_cast
4. reinterpret_cast
https://learn.microsoft.com/ko-kr/cpp/cpp/casting-operators?view=msvc-170
캐스팅 연산자
자세한 정보: 캐스팅 연산자
learn.microsoft.com
static_cast
static_cast는 '말이 되는' 문법이면 통과시켜준다.
기본형 간 변환, 업캐스팅, enum<->int 등 일반적으로 많이 사용하는 캐스팅에 static_cast를 사용한다.
int _tmain(void)
{
Base* b = new Base;
Derived* d = static_cast<Derived*>(b);
return 0;
}
다만 위와 같은 다운캐스팅의 경우에는 static_cast가 가능하지만, 실제 부모 포인터가 가리키는 객체가 실제로는 어떤 타입일지 알 수 없기 때문에 다운캐스팅에 static_cast를 사용하는 것은 위험할 수 있다.
따라서 이러한 경우에는 RTTI(RunTime Type Id)를 사용하는 dynamic_cast를 사용해볼 수 있다.
dynamic_cast
https://learn.microsoft.com/ko-kr/cpp/cpp/run-time-type-information?view=msvc-170
런타임 형식 정보
다음에 대해 자세히 알아보세요. 런타임 형식 정보
learn.microsoft.com
dynamic_cast는 RTTI를 활용해 다형성, 상속관계 내의 캐스팅이 적절한 지 여부를 런타임에 잡아준다.
만약 해당 클래스가 실제로 캐스팅한 타입과 일치하는지 확인하고, 아니라면 nullptr을 반환해준다.
class Base
{
public:
virtual ~Base()
{
cout << "Base" << endl;
}
};
class Derived1 : public Base
{
~Derived1()
{
cout << "Derived1" << endl;
}
};
class Derived2 : public Base
{
~Derived2()
{
cout << "Derived1" << endl;
}
};
int _tmain(void)
{
Base* b = new Derived2;
Derived1* d1 = static_cast<Derived1*>(b);
Derived1* d2 = dynamic_cast<Derived1*>(b);
return 0;
}
현재 위의 코드는 Derived2를 Derived1으로 변경하려고 시도한다. Derived1, Derived2는 Base를 상속받았지만 관계가 없는 객체이다. 따라서 컴파일에는 문제가 없지만, 런타임 실행시에 d2에는 nullptr을 반환하게 된다.
Derived1* d2 = dynamic_cast<Derived1*>(b);
00B71189 6A 00 push 0
00B7118B 68 C0 50 B7 00 push offset Derived1 `RTTI Type Descriptor' (0B750C0h)
00B71190 68 D8 50 B7 00 push offset Base `RTTI Type Descriptor' (0B750D8h)
00B71195 6A 00 push 0
00B71197 8B 55 F4 mov edx,dword ptr [b]
00B7119A 52 push edx
00B7119B E8 F3 15 00 00 call ___RTDynamicCast (0B72793h)
00B711A0 83 C4 14 add esp,14h
00B711A3 89 45 EC mov dword ptr [d2],eax
위와 같이 RTTI를 활용해 type descriptor를 받아오고 이를 인자로 함수를 내부적으로 호출하고 있음을 알 수 있다.
런타임 메커니즘이고, 다형성 관계를 파악하는 작업이 필요하므로 이는 실행 중 성능저하를 일으킬 수 있다.
따라서 실제로는 사용을 지양한다.
const_cast
const를 때고 붙일 수 있는 캐스팅 방법
const는 실제로 해당 메모리를 보호하는 등의 행위를 하지 않기 때문에 컴파일러의 에러를 잡는 역할이 끝이다.
reinterpret_cast
타입 간의 물리적인 의미는 무시하고 메모리 비트 패턴을 그대로 해석해서 다른 타입으로 변환하는 캐스팅이다.
의미를 정말 잘 파악하고 사용해야 한다.
'C, C++ > C, C++ 잡지식' 카테고리의 다른 글
| CreateThread와 _beginthreadex 간단하게 알아보기 (0) | 2025.10.08 |
|---|---|
| 구조체? (0) | 2025.06.14 |
| 가상 함수 virtual (1) | 2025.06.06 |
| malloc과 new, free와 delete (2) | 2025.05.31 |
| 동적할당 분석해보기(1) (0) | 2025.05.01 |