Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      dynamic_cast conversion

      From cppreference.com
      <cpp‎ |language
       
       
      C++ language
      General topics
      Flow control
      Conditional execution statements
      Iteration statements (loops)
      Jump statements
      Functions
      Function declaration
      Lambda function expression
      inline specifier
      Dynamic exception specifications(until C++17*)
      noexcept specifier(C++11)
      Exceptions
      Namespaces
      Types
      Specifiers
      constexpr(C++11)
      consteval(C++20)
      constinit(C++20)
      Storage duration specifiers
      Initialization
      Expressions
      Alternative representations
      Literals
      Boolean -Integer -Floating-point
      Character -String -nullptr(C++11)
      User-defined(C++11)
      Utilities
      Attributes(C++11)
      Types
      typedef declaration
      Type alias declaration(C++11)
      Casts
      Memory allocation
      Classes
      Class-specific function properties
      Special member functions
      Templates
      Miscellaneous
       
      Expressions
      General
      Literals
      Operators
      Conversions
       

      Safely converts pointers and references to classes up, down, and sideways along the inheritance hierarchy.

      Contents

      [edit]Syntax

      dynamic_cast<target-type>(expression)
      target-type - pointer to complete class type, reference to complete class type, or pointer to (optionally cv-qualified)void
      expression -lvalue(until C++11)glvalue(since C++11) of a complete class type iftarget-type is a reference, prvalue of a pointer to complete class type iftarget-type is a pointer

      [edit]Explanation

      For the convenience of description, “expression or the result is a reference toT” means that “it is a glvalue of typeT, which follows the convention ofdecltype(since C++11).

      Only the following conversions can be done withdynamic_cast, except when such conversions wouldcast away constness (or volatility).

      1) If the type ofexpression is exactlytarget-type or a less cv-qualified version oftarget-type, the result is the value ofexpression with typetarget-type. In other words,dynamic_cast can be used toadd constness. An implicit conversion andstatic_cast can perform this conversion as well.
      2) Iftarget-type is “pointer to (possibly cv-qualified)Base” and the type ofexpression is “pointer to (possibly cv-qualified)Derived” such thatBase is a base class ofDerived, the result is
      • a null pointer value ifexpression is a null pointer value, or
      • a pointer to the uniqueBasesubobject of theDerived object pointed to byexpression otherwise. In other words,dynamic_cast can be used toupcast pointers, from derived to base. An implicit conversion andstatic_cast can perform this conversion as well.
      3) Iftarget-type is “reference to (possibly cv-qualified)Base” and the type ofexpression is “(possibly cv-qualified)Derived” such thatBase is a base class ofDerived, the result is the uniqueBase subobject of theDerived object referred to byexpression. In other words,dynamic_cast can be used toupcast references, from derived to base. An implicit conversion andstatic_cast can perform this conversion as well.
      4) Ifexpression is a null pointer value of apolymorphic type, the result is the null pointer value oftarget-type.
      5) Otherwise,expression must be a pointer or reference to an object ofpolymorphic type within itslifetime or within its period of construction or destruction whose type issimilar to the type ofexpression (otherwise the behavior is undefined)
      a) Ifexpression is a pointer to (possibly cv-qualified)void, the result is a pointer to themost derived object pointed to byexpression.
      b) Otherwise a runtime check is applied to see if the object pointed/referred to byexpression can be converted to the typeTarget, pointed or referred to bytarget-type:
      i) If, in the most derived object pointed/referred to byexpression,expression points/refers to a public base class subobject of aTarget object, and if only one object of typeTarget is derived from the subobject pointed/referred to byexpression, the result points/refers to thatTarget object. In other words,dynamic_cast can be used todowncast pointers/references, from base to derived.
      ii) Otherwise, ifexpression points/refers to a public base class subobject of the most derived object, and the type of the most derived object has an unambiguous and public base class of typeTarget, the result points/refers to theTarget subobject of the most derived object. In other words,dynamic_cast can be used tocrosscast (or side-cast) pointers/references, between two types derived from the same base.
      iii) Otherwise, the runtime check fails.
      • Iftarget-type is a pointer type, the result is the null pointer value oftarget-type.
      • Iftarget-type is a reference type, an exception of a type that would match ahandler of typestd::bad_cast is thrown.

      Whendynamic_cast is used in a constructor or a destructor (directly or indirectly), andexpression refers to the object that's currently under construction/destruction, the object is considered to be the most derived object. Iftarget-type is not a pointer or reference to the constructor's/destructor's own class or one of its bases, the behavior is undefined.

      Similar to other cast expressions, the result is:

      • an lvalue iftarget-type is a reference type
      • an rvalue iftarget-type is a pointer type
      (until C++11)
      • an lvalue iftarget-type is an lvalue reference type (expression must be an lvalue)
      • an xvalue iftarget-type is an rvalue reference type (expressionmay be lvalue or rvalue(until C++17)must be a glvalue (prvalues arematerialized)(since C++17) of a complete class type)
      • a prvalue iftarget-type is a pointer type
      (since C++11)

      [edit]Notes

      A downcast can also be performed withstatic_cast, which avoids the cost of the runtime check, but it is only safe if the program can guarantee (through some other logic) that the object pointed to byexpression is definitelyDerived.

      Some forms ofdynamic_cast rely onrun-time type identification (RTTI), that is, information about each polymorphic class in the compiled program. Compilers typically have options to disable the inclusion of this information.

      [edit]Keywords

      dynamic_cast

      [edit]Example

      Run this code
      #include <iostream> struct V{virtualvoid f(){}// must be polymorphic to use runtime-checked dynamic_cast}; struct A:virtual V{}; struct B:virtual V{    B(V* v, A* a){// casts during construction (see the call in the constructor of D below)dynamic_cast<B*>(v);// well-defined: v of type V*, V base of B, results in B*dynamic_cast<B*>(a);// undefined behavior: a has type A*, A not a base of B}}; struct D: A, B{    D(): B(static_cast<A*>(this), this){}}; struct Base{virtual ~Base(){}}; struct Derived: Base{virtualvoid name(){}}; int main(){    D d;// the most derived object    A& a= d;// upcast, dynamic_cast may be used, but unnecessary [[maybe_unused]]    D& new_d=dynamic_cast<D&>(a);// downcast[[maybe_unused]]    B& new_b=dynamic_cast<B&>(a);// sidecast     Base* b1= new Base;if(Derived* d=dynamic_cast<Derived*>(b1); d!= nullptr){std::cout<<"downcast from b1 to d successful\n";        d->name();// safe to call}     Base* b2= new Derived;if(Derived* d=dynamic_cast<Derived*>(b2); d!= nullptr){std::cout<<"downcast from b2 to d successful\n";        d->name();// safe to call}     delete b1;    delete b2;}

      Output:

      downcast from b2 to d successful

      [edit]Defect reports

      The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

      DRApplied toBehavior as publishedCorrect behavior
      CWG 1269C++11the runtime check was not performed for xvalue
      expression s iftarget-type is an rvalue reference type
      performed
      CWG 2861C++98expression could point/refer to a type-inaccessible objectthe behavior is undefined in this case

      [edit]References

      • C++23 standard (ISO/IEC 14882:2024):
      • 7.6.1.7 Dynamic cast [expr.dynamic.cast]
      • C++20 standard (ISO/IEC 14882:2020):
      • 7.6.1.6 Dynamic cast [expr.dynamic.cast]
      • C++17 standard (ISO/IEC 14882:2017):
      • 8.2.7 Dynamic cast [expr.dynamic.cast]
      • C++14 standard (ISO/IEC 14882:2014):
      • 5.2.7 Dynamic cast [expr.dynamic.cast]
      • C++11 standard (ISO/IEC 14882:2011):
      • 5.2.7 Dynamic cast [expr.dynamic.cast]
      • C++98 standard (ISO/IEC 14882:1998):
      • 5.2.7 Dynamic cast [expr.dynamic.cast]
      • C++03 standard (ISO/IEC 14882:2003):
      • 5.2.7 Dynamic cast [expr.dynamic.cast]

      [edit]See also

      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/language/dynamic_cast&oldid=182014"

      [8]ページ先頭

      ©2009-2025 Movatter.jp