dynamic_cast conversionSafely converts pointers and references to classes up, down, and sideways along the inheritance hierarchy.
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 if target-type is a reference, prvalue of a pointer to complete class type if target-type is a pointer |
If the cast is successful, dynamic_cast returns a value of type target-type. If the cast fails and target-type is a pointer type, it returns a null pointer of that type. If the cast fails and target-type is a reference type, it throws an exception that matches a handler of type std::bad_cast.
For the convenience of description, "expression or the result is a reference to T" means that "it is a glvalue of type T", which follows the convention of decltype.
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 target-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 target-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 target-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) |
Derived. #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
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 expression s if target-type is an rvalue reference type | performed |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/language/dynamic_cast