dynamic_cast
dynamic_cast
主要用于“安全地向下转型”
dynamic_cast
用于类继承层次间的指针或引用转换。主要用于执行“安全的向下转型”,对于向上转换,没有问题。
dynamic_cast<new_type>(expression)
new_type:指向完全类型的指针或引用,或者是指向void类型的指针
expression:如果new_type是引用,则expression是一个完全类类型的左值;如果new_type是指针,则expression是一个指向完全类类型的右值指针
如果转换成功,则dynamic_cast
返回new_type
类型的值。如果转换失败,并且new_type
是指针,则返回空指针;如果new_type
是引用,则返回std::bad_cast
错误。
解释
dynamic_cast
不涉及去除const
和volatile
。
- 如果
expression
是一个空指针,则转换的结果就是指向new_type
的空指针。 - 如果
new_type
是一个指向Base
的指针/引用,expression
是一个指向Derived
的指针/引用,Base
是唯一的,Derived
可访问的基类。转换的结果就是expression
指向/引用的子类对象的基类子对象。 - 如果
expression
是一个指针/引用,指向多态类型基类,new_type
是一个指针/引用,指向子类类型。- 如果,
expression
指向/引用一个derived
对象的公共base
部分,并且这个子类类型的对象来源于expression
指向的derived
对象,这个转换的结果是指向derived
的指针/引用。 - 如果,
expression
指向/引用一个最子类对象,这个最子类对象有唯一的derived
的基类部分,这个转换的结果就是指向derived
的指针/引用。 - 否则,如果是指针,则返回指向
new_type
的空指针;引用的话,就返回std::bad_cast
错误。
- 如果,
#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))
{
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))
{
std::cout << "downcast from b2 to d successful\n";
d->name(); // safe to call
}
delete b1;
delete b2;
}