dynamic_cast conversion
动态[医]铸造转换
安全地沿继承层次结构将指针和引用向上、向下和横向地转换为类。
句法
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 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. |
如果演员成功了,dynamic_cast
返回类型的值。new_type
.如果演员阵容失败new_type
是指针类型,则返回该类型的空指针。如果演员阵容失败new_type
是引用类型,则引发与类型处理程序匹配的异常。std::bad_cast
...
解释
只有以下转换可以使用dynamic_cast
,除非这种转换会被抛弃。恒恒
或波动率
...
1%29如果表达式的类型完全是新的[医]输入或少于cv的新版本[医]类型,则结果是表达式的值,并使用新类型。[医]类型。%28,换言之,dynamic_cast
可以用来增加一致性。含蓄的演员static_cast
也可以执行此转换。%29
2%29如果表达式的值为空指针值,则结果为新类型的空指针值。[医]类型。
3%29如新[医]类型是指针或引用。Base
,表达式的类型是指针或引用。Derived
,在哪里Base
的唯一、可访问的基类。Derived
,则结果是指向Base
类中的子对象。Derived
由表达式指向或标识的对象。%28注:隐式演员和static_cast
也可以执行此转换。%29
4%29如果表达式是指向多态型,和new_type
是指向void
,结果是指向表达式指向或引用最多的派生对象的指针。
5%29如果表达式是指向多态型Base
,和new_type
是指向类型的指针或引用。Derived
执行运行时检查:
检查由表达式指向/标识的最派生对象%29。如果在该对象中,表达式点/指的是Derived
,如果只有一个子对象Derived
类型派生自由表达式指定/标识的子对象,然后转换点/表示的结果Derived
次目标。%28这被称为“下降”
否则,如果表达式点/引用派生对象最多的公共基,同时,派生最多的对象具有类型明确的公共基类,则为B%29。Derived
的结果/指的是Derived
%28这被称为“侧播”
C%29否则,运行时检查将失败。如果dynamic_cast
在指针上使用,类型新的空指针值。[医]类型返回。如果它用于引用,则例外std::bad_cast
被扔了。
6%29dynamic_cast
在构造函数或析构函数%28中直接或间接地使用%29,表达式指当前正在构造/销毁的对象%27s,该对象被认为是最派生的对象。如果是新的[医]类型不是一个指针或对构造函数%27s/析构函数%27s自己的类或其基之一的引用,该行为是未定义的。
与其他强制转换表达式类似,结果是:
- 如果是新的[医]类型是lvalue引用类型%28表达式必须是lvalue%29
- 如果是新的xvalue[医]类型是rvalue引用类型%28表达式可能是lvalue或rvalue%28,直到C++17%29必须是glvalue%28,因为C++17%29是完整类类型%29的
- 如果是新的,则在本例中为%28。[医]类型是指针类型%29
注
也可以用static_cast
,这避免了运行时检查的成本,但只有当程序能够通过表达式所指向的对象绝对是其他逻辑%29来保证%28时,它才是安全的。Derived
...
关键词
dynamic_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((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
D& new_d = dynamic_cast<D&>(a // downcast
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;
}
二次
产出:
二次
downcast from b2 to d successful
二次
另见
- 康斯特[医]铸造
- 静态[医]铸造
- 重释[医]铸造
- 显式铸造
- 隐式转换
© cppreference.com
在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。