dynamic_cast
conversion
Safely converts pointers and references to classes up, down, and sideways along the inheritance hierarchy.
Syntax
dynamic_cast < new-type > ( expression ) |
new-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 if new-type is a reference, prvalue of a pointer to complete class type if new-type is a pointer. |
If the cast is successful, dynamic_cast
returns a value of type new-type. If the cast fails and new-type is a pointer type, it returns a null pointer of that type. If the cast fails and new-type is a reference type, it throws an exception that matches a handler of type std::bad_cast
.
Explanation
Only the following conversions can be done with dynamic_cast
, except when such conversions would cast away constness or volatility.
dynamic_cast
can be used to add constness. An implicit conversion and
static_cast
can perform this conversion as well.)
Base
, and the type of
expression is a pointer or reference to
Derived
, where
Base
is a unique, accessible base class of
Derived
, the result is a pointer or reference to the
Base
class subobject within the
Derived
object pointed or identified by
expression. (Note: an implicit conversion and
static_cast
can perform this conversion as well.)
void
, the result is a pointer to the most derived object pointed or referenced by
expression.
Base
, and
new-type is a pointer or reference to the type
Derived
a runtime check is performed:
Derived
, and if only one object of
Derived
type is derived from the subobject pointed/identified by
expression, then the result of the cast points/refers to that
Derived
object. (This is known as a "downcast".)
Derived
, the result of the cast points/refers to that
Derived
(This is known as a "sidecast".)
dynamic_cast
is used on pointers, the null pointer value of type
new-type is returned. If it was used on references, the exception
std::bad_cast
is thrown.
dynamic_cast
is used in a constructor or a destructor (directly or indirectly), and
expression refers to the object that's currently under construction/destruction, the object is considered to be the most derived object. If
new-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:
|
(until C++11) |
|
(since C++11) |
Notes
- A downcast can also be performed with
static_cast
, which avoids the cost of the runtime check, but it's only safe if the program can guarantee (through some other logic) that the object pointed to by expression is definitelyDerived
. - Some forms of
dynamic_cast
rely on runtime 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.
Keywords
Example
#include <iostream> struct V { virtual void 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 { virtual void 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
Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
CWG 1269 | C++11 | the runtime check was not performed for xvalue expressions if new-type is a rvalue reference type |
performed |
See also
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/language/dynamic_cast