C++에서 안전한 형 변환(type casting)은 static_cast, dynamic_cast, const_cast, reinterpret_cast와 같은 변환 연산자를 통해 제공됩니다.
nullptr를, 참조에는 예외를 발생시킵니다.사용 시기:
dynamic_cast를 사용하십시오. 간단한/호환 가능한 타입 간의 변환에는 static_cast를 사용하십시오.예제:
struct Base { virtual ~Base() {} }; struct Derived : Base { void foo() {} }; void test_cast(Base* base) { // 하위 클래스에 대한 안전한 변환 Derived* d = dynamic_cast<Derived*>(base); if (d) { d->foo(); } }
질문: 객체가 실제로 파생 클래스의 인스턴스가 아닌 경우 static_cast를 사용하여 기본 클래스를 파생 클래스로 변환할 수 있습니까?
답변: 예, static_cast는 컴파일되지만, 객체가 실제로 파생 클래스의 객체가 아니면 동작이 정의되지 않습니다. 오직 dynamic_cast만이 그러한 변환의 안전성을 보장합니다. 객체의 실제 유형에 확신이 있을 때만 downcast를 위한 static_cast 사용이 허용됩니다.
이야기
대규모 임베디드 시스템에서 부모 클래스와 자식 클래스 간의 변환이 static_cast를 통해 이루어졌습니다. 일부 경우, 존재하지 않는 필드를 참조하려다 충돌이 발생하였으며, 프로그램이 다른 유형의 메모리를 해석하려 했습니다.
이야기
플러그인 아키텍처 개발 시, 프로그래머들이 서로 다른 타입 간의 포인터 변환에 reinterpret_cast를 사용하여 실행 시 쓰레기 값을 읽거나 충돌이 발생하는 경우가 많았습니다. 특히 DLL을 통한 동적 변환 시 그러했습니다.
이야기
일반 기업 프레임워크에서는 기본 클래스에 가상 소멸자를 잊어버려 dynamic_cast의 올바른 작동이 불가능해졌고, 기본 클래스에 대한 포인터를 통해 객체를 삭제할 때 메모리 누수 및 손상으로 이어졌습니다.