什么类型的Cast从父母到孩子

What Type of Cast to Go from Parent to Child?

本文关键字:父母 孩子 Cast 类型 什么      更新时间:2023-10-16

这个问题是关于应该使用哪种c++风格强制转换来进行这种转换。我知道一个C风格的强制转换可以做到这一点。

对于以下class结构:

class Foo {};
class Bar : public Foo {};

假设我给定:Foo* ptr;,我想将其转换为Bar*,我应该使用哪种类型的转换?似乎我必须使用dynamic_cast,因为它是:

用于多态类型的转换

我想避免dynamic_cast,因为它是一个运行时强制转换

您是正确的,dynamic_cast通常最适合这种情况。但是,如果知道指针实际上指向派生类的对象,则可以使用static_cast进行转换。如果你错了,指针是而不是派生类,你会得到未定义的行为。

static_cast将工作得很好,只要你确定你正在转换的对象确实是你所期望的类型。根据您给出的示例,看起来您是确定的。

为清楚起见:

我想避免dynamic_cast,因为它是一个运行时强制转换。

好吧,你有一个运行时类型(给定基类的静态类型引用,你通常不能知道对象的动态类型),所以运行时强制转换是唯一完全安全的选择。

如果你认为你的对象实际上是一个Bar,但是你错了,dynamic_cast<Bar*>会给你一个nullptr,或者dynamic_cast<Bar&>会抛出一个异常。无论哪种方式,您都有机会在运行时处理运行时错误。正如M.M所指出的,这只有在基类拥有或继承了至少一个虚方法时才可用。

现在,如果碰巧你可以静态地确定对象的动态类型确实 Bar,你可以使用static_cast。然而,如果你错了,你有未定义的行为,没有机会检测或处理错误。

struct Foo { virtual ~Foo(){} };
struct Bar : public Foo {};
// safe, may return nullptr
Bar* safe_ptr_cast(Foo *f) { return dynamic_cast<Bar*>(f); }
// safe, may throw but you can catch it
Bar& safe_ref_cast(Foo &f) { return dynamic_cast<Bar&>(f); }
// unsafe - if you're wrong, you just broke everything
Bar* unsafe_ptr_cast(Foo *f) { return static_cast<Bar*>(f); }

顺便说一下,如果您对运行时强制转换的问题是性能,那么在您有代码要分析之前冒着UB的风险来节省名义上的时间是过早优化的定义。