dynamic_cast
conversion
클래스의 상속 계층 구조를 따라 위, 아래, 옆으로 안전하게 포인터와 참조를 변환합니다.
목차 |
구문
dynamic_cast<
target-type
>(
expression
)
|
|||||||||
| target-type | - | 완전한 클래스 타입에 대한 포인터, 완전한 클래스 타입에 대한 참조, 또는 (선택적으로 cv-qualified) void 에 대한 포인터 |
| expression | - | lvalue (C++11 이전) glvalue (C++11 이후) target-type 이 참조인 경우 완전한 클래스 타입의 lvalue, target-type 이 포인터인 경우 완전한 클래스 타입에 대한 포인터의 prvalue |
설명
설명의 편의를 위해, "
expression
또는 결과가
T
에 대한 참조이다"는 "이것이
T
타입의 glvalue이다"를 의미합니다
, 이는
decltype
의 관례를 따릅니다
(since C++11)
.
다음 변환만 dynamic_cast 로 수행할 수 있으며, 이러한 변환이 constness 제거 (또는 volatility 제거)를 유발하는 경우는 예외입니다.
Base
에 대한 포인터"이고
expression
의 타입이 "(cv 한정자가 있을 수 있는)
Derived
에 대한 포인터"이며
Base
가
Derived
의 기본 클래스인 경우, 결과는
- expression 이 null 포인터 값인 경우 null 포인터 값, 또는
-
그렇지 않은 경우
expression
이 가리키는
Derived객체의 고유한Base서브객체 를 가리키는 포인터입니다. 즉, dynamic_cast 는 파생 클래스에서 기본 클래스로 포인터를 업캐스트 하는 데 사용할 수 있습니다. 암시적 변환과 static_cast 도 이 변환을 수행할 수 있습니다.
Base
에 대한 참조"이고
expression
의 타입이 "(cv 한정자가 있을 수 있는)
Derived
"이며
Base
가
Derived
의 기본 클래스인 경우, 결과는
expression
이 참조하는
Derived
객체 내 유일한
Base
서브객체입니다. 즉,
dynamic_cast
는 파생 클래스에서 기본 클래스로 참조를
업캐스트
하는 데 사용될 수 있습니다. 암시적 변환과
static_cast
도 이 변환을 수행할 수 있습니다.
Target
타입으로 변환될 수 있는지 확인합니다:
Target
객체의 public 기반 클래스 하위 객체를 가리키거나 참조하고,
expression
이 가리키거나 참조하는 하위 객체로부터 파생된
Target
타입의 객체가 단 하나만 존재하는 경우,
결과는 해당
Target
객체를 가리키거나 참조합니다. 즉,
dynamic_cast
는 포인터/참조를
다운캐스트
하는 데 사용될 수 있으며, 이는 기반 클래스에서 파생 클래스로의 변환을 의미합니다.
Target
타입의 명확하고 public인 기반 클래스를 갖는 경우, 결과는 최종 파생 객체의
Target
하위 객체를 가리키거나 참조합니다. 다른 말로,
dynamic_cast
는 동일한 기반에서 파생된 두 타입 간에 포인터/참조의
교차 캐스팅
(또는 사이드 캐스팅)에 사용될 수 있습니다.
- 만약 target-type 이 포인터 타입인 경우, 결과는 target-type 의 널 포인터 값입니다.
- 만약 target-type 이 참조 타입인 경우, std::bad_cast 타입의 핸들러 와 일치하는 타입의 예외가 발생합니다.
생성자나 소멸자 내에서(직접적 또는 간접적으로) dynamic_cast 가 사용되고, expression 이 현재 생성/소멸 중인 객체를 참조할 때, 해당 객체는 가장 파생된 객체로 간주됩니다. 만약 target-type 이 생성자/소멸자 자신의 클래스나 그 기반 클래스 중 하나에 대한 포인터나 참조가 아닌 경우, 그 동작은 정의되지 않습니다.
다른 형변환 표현식과 유사하게, 결과는 다음과 같습니다:
|
(C++11 이전) |
|
(C++11 이후) |
참고 사항
다운캐스트는
static_cast
를 사용해서도 수행할 수 있으며, 이는 런타임 검사의 비용을 피할 수 있지만,
expression
이 가리키는 객체가 반드시
Derived
라는 것을 프로그램이 (다른 논리를 통해) 보장할 수 있는 경우에만 안전합니다.
일부 형태의 dynamic_cast 는 런타임 타입 식별 (RTTI), 즉 컴파일된 프로그램 내의 각 다형성 클래스에 대한 정보에 의존합니다. 컴파일러는 일반적으로 이 정보의 포함을 비활성화하는 옵션을 제공합니다.
키워드
예제
#include <iostream> struct V { virtual void f() {} // 런타임 검사 dynamic_cast를 사용하려면 반드시 다형성이 있어야 함 }; struct A : virtual V {}; struct B : virtual V { B(V* v, A* a) { // 생성 중 캐스트 (아래 D의 생성자 호출 참조) dynamic_cast<B*>(v); // 올바르게 정의됨: v는 V* 타입, V는 B의 기반 클래스, 결과는 B* dynamic_cast<B*>(a); // 정의되지 않은 동작: a는 A* 타입, A는 B의 기반 클래스가 아님 } }; struct D : A, B { D() : B(static_cast<A*>(this), this) {} }; struct Base { virtual ~Base() {} }; struct Derived : Base { virtual void name() {} }; int main() { D d; // 가장 파생된 객체 A& a = d; // 업캐스트, dynamic_cast를 사용할 수 있지만 불필요함 [[maybe_unused]] D& new_d = dynamic_cast<D&>(a); // 다운캐스트 [[maybe_unused]] B& new_b = dynamic_cast<B&>(a); // 사이드캐스트 Base* b1 = new Base; if (Derived* d = dynamic_cast<Derived*>(b1); d != nullptr) { std::cout << "downcast from b1 to d successful\n"; d->name(); // 안전하게 호출 가능 } Base* b2 = new Derived; if (Derived* d = dynamic_cast<Derived*>(b2); d != nullptr) { std::cout << "downcast from b2 to d successful\n"; d->name(); // 안전하게 호출 가능 } delete b1; delete b2; }
출력:
downcast from b2 to d successful
결함 보고서
다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.
| DR | 적용 대상 | 게시된 동작 | 올바른 동작 |
|---|---|---|---|
| CWG 1269 | C++11 |
대상-유형이 rvalue 참조 유형일 때 xvalue
expression 에 대해 런타임 검사가 수행되지 않았음 |
수행됨 |
| CWG 2861 | C++98 | expression 이 유형에 접근 불가능한 객체를 가리키거나 참조할 수 있었음 | 이 경우 동작이 정의되지 않음 |
참조문헌
- C++23 표준 (ISO/IEC 14882:2024):
-
- 7.6.1.7 Dynamic cast [expr.dynamic.cast]
- C++20 표준(ISO/IEC 14882:2020):
-
- 7.6.1.6 Dynamic cast [expr.dynamic.cast]
- C++17 표준 (ISO/IEC 14882:2017):
-
- 8.2.7 Dynamic cast [expr.dynamic.cast]
- C++14 표준(ISO/IEC 14882:2014):
-
- 5.2.7 Dynamic cast [expr.dynamic.cast]
- C++11 표준(ISO/IEC 14882:2011):
-
- 5.2.7 Dynamic cast [expr.dynamic.cast]
- C++98 표준(ISO/IEC 14882:1998):
-
- 5.2.7 Dynamic cast [expr.dynamic.cast]
- C++03 표준(ISO/IEC 14882:2003):
-
- 5.2.7 Dynamic cast [expr.dynamic.cast]