프로그래밍백엔드 개발자 / C++ 개발자

C++에서 안전한 형 변환(type casting)을 어떻게 구현하나요? static_cast와 dynamic_cast의 차이점은 무엇이며, 언제 사용하는 것이 좋습니까? 잘못된 형 변환으로 인해 발생할 수 있는 오류를 설명하십시오.

Hintsage AI 어시스턴트로 면접 통과

답변.

C++에서 안전한 형 변환(type casting)은 static_cast, dynamic_cast, const_cast, reinterpret_cast와 같은 변환 연산자를 통해 제공됩니다.

  • static_cast: 상속 관계가 있는 클래스와 숫자 타입 간과 같은 호환 가능한 타입 간의 일반적인 변환에 사용됩니다(런타임 타입 검증 없이).
  • dynamic_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의 올바른 작동이 불가능해졌고, 기본 클래스에 대한 포인터를 통해 객체를 삭제할 때 메모리 누수 및 손상으로 이어졌습니다.