向下投射实际上是有用的?
在实现奇怪地重复出现的模板模式时,它非常有用:
template <class T>
struct Base
{
void interface()
{
// ...
static_cast<T*>(this)->implementation();
// ...
}
static void static_func()
{
// ...
T::static_sub_func();
// ...
}
};
struct Derived : Base<Derived>
{
void implementation();
static void static_sub_func();
};
公共基类模板接口提供了将调用委托给派生类实现的定义,派生类实现是通过将基类的此
指针向下传送到相应派生类的指针类型(对于基类模板的特定专门化),然后动态分派到派生类函数来实现的(对于非静态成员函数)。
注意,在这种意义上的向下转换不一定需要在动态转换方面实现; 在本例中,静态强制转换用于将基类指针(this
)强制转换到相应的派生类指针。
没有使用向下转换的常见习惯用法/模式,因为它不是很有用。 使用向下投射表示设计不佳。
如果您发现自己处于一种罕见的情况,您认为您需要向下转换,因为您已经被框架或库的设计画成了墙角,那么要知道动态转换是为您准备的。 但大多数时候(希望如此),你不会处于那种情况。
如果你想不出一个情况下你会需要下降,那么你是在一个好的地方,并与大多数程序员相伴。
>
您从不太信任的外部/用户代码获取抽象类。 并且您需要验证它是否与您期望的类型匹配。 如果不匹配,则报告错误而不是使用UB。 此外,如果你要向用户/外部代码公开太多你的代码/类--所以你把它们隐藏在接口类后面--这将是一个问题。
对于一般的对象管理器类很有用-它存储抽象类而不需要理解那些是什么。 因此,每当用户试图获取这些类型中的一个并强制转换为适当的类型时,它应该应用动态强制转换以确保用户不会搞乱这些类型。
它用于处理具有非平凡层次结构的复杂类--对此,简单的指针强制转换可能会失败。 然而,从总体上处理这类类是不明智的。