每当您需要静态向上投射时,模板可能可以满足您的目的。
template <typename TTo> derived_cast ( BaseClass* b ) {
static_assert( std::is_base_of<BaseClass, TTo>::value, "You can't cast to a class that's not derived from BaseClass!" );
return static_cast<TTo*>( b );
}
然后语法变得更加压缩:
Derived* d = derived_cast<Derived>( b );
确保TTo
实际派生的 static_assert 等等。
现在,对于运行时,您必须使用dynamic_cast
,但这涉及到您所拥有的代码所暗示的其他内容。
编辑:超越这一点是一种疯狂的龙。
在 C++ 中,动态转换和操作对象(在编译时不知道该类型)是不可能的,除非使用健壮的基类或 if/else
某种运行时标识符,然后提供静态类型信息。在几乎所有情况下,您最好只virtual
在基类上使用一个方法,然后在派生类中覆盖它们。当您必须不断添加额外的情况时,打开字符串和其他东西不仅缓慢而且痛苦:不要这样做。但是,如果你不理会我的建议,这里有一些你可以使用的内置部件来获得你想要的东西:
typeid
- 定义实现定义但对类唯一的对象 ( type_info
) 的运算符,该对象与该类进行唯一比较。您可以比较它们typeid( Dog) == typeid( Dog )
并正确获得真/假。这将为您提供一些运行时键入信息。
dynamic_cast
- 在向上转换或转换为某种类型的类时失败的转换(简化定义,更多信息请参见cppreference ondynamic_cast
)。您可以使用它来动态转换指针和其他类似的东西,它会null
在转换失败时返回。它在这里可能对您有所帮助,但您仍然需要静态地了解您正在使用的类型(例如,在打开 typeid 之后)。
有了这两个,您可以更好地实现您在另一个答案中看到的string
用法。但仅此而已。其他任何事情都需要诸如boost::variant
更强大的基类或不同的设计之类的东西。一个更强大的基类听起来像是你可以在这里使用的,但我不能 100% 肯定地说。
祝你好运!