是否可以在运行时动态选择要转换的类型?
例如,假设我有:
ClassType * pointer=static_cast<ClassType*>(baseClassPointer);
但是,在运行时,我想选择ClassType
是什么,而不是将其硬编码到函数中。
这可能吗?我想要使用它的两种方式是传递包含我想要使用的类型名称的实际char *
,或以某种方式从现有类中提取类型信息并将其用作演员。
我想要这样做的原因是,我有一个来自公共基类的几个派生类。我可以为每个派生类获取基类的基本功能,但是如果我想要一个指针来访问仅存在于派生类中的某些特定功能,我需要像这样强制转换指针。我希望有一个函数允许我为任何派生类动态执行此转换。
答案 0 :(得分:2)
模板可以在此处为您的目的服务,无论您何时需要静态地向上投射。
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 );
static_assert确保TTo
实际上是派生的等等。
现在,对于运行时,你必须使用dynamic_cast
,但这涉及到你所拥有的代码所暗示的其他内容。
编辑: 除此之外还有一种疯狂的龙。
在C ++中,动态转换和操作对象(在编译时不知道该类型)是不可能的,除非在某种情况下使用强大的基类或 if/else
运行时标识符然后提供静态类型信息。在几乎所有情况下,最好只在基类上使用virtual
方法,然后在派生类中重写它们。当你不得不继续添加额外的案例时,打开字符串和其他东西不仅缓慢而且痛苦:不要这样做。但是,如果你要忽略我的建议,可以使用一些内置的部分来获得你想要的东西:
typeid
- 一个运算符,它定义了一个实现定义但对类唯一的对象(type_info
),该对象唯一地与该类进行比较。您可以比较它们typeid( Dog) == typeid( Dog )
并正确获取true / false。这将允许您一些运行时键入信息。
dynamic_cast
- 在向上转换或某个类别的某个类上失败的强制转换(精简定义,有关详细信息,请参阅cppreference on dynamic_cast
)。您可以使用它来动态地转换指针和其他类似的东西,并在失败时返回null
。它可能会对你有所帮助,但你仍然需要知道你正在使用的静态类型(在打开之后,比如,typeid)。
使用这两个,您可以使用string
用法更好地实现您在其他答案中看到的内容。但那是关于它的。其他任何东西都需要boost::variant
,更强大的基类或不同的设计。一个更强大的基类听起来像你可以在这里使用,但我不能100%肯定地说。
答案 1 :(得分:1)
发现糟糕的设计! 覆盖派生类怎么样?你正在搞一些非常危险的东西
答案 2 :(得分:1)
如果您有基类Animal,并且您有派生类Dog和Cat,您可以随时将Animal转换为Dog或Cat(如果您知道它是哪个):
void doCustomOperation(Animal *animal, string runtimeDecision) {
if (runtimeDecision == "dog") {
((Dog *)animal).bark();
}
if (runtimeDecision == "cat") {
((Cat *)animal).chaseMouse();
}
}
答案 3 :(得分:1)
即使您可以在运行时执行此操作(我认为您无法做到),您将使用派生类指针执行什么操作?您在编写代码时不会知道您将获得什么类型的对象,那么您如何知道可以调用哪些方法?
我认为您最好将虚拟方法添加到基类以捕获必要的功能,或者您可以使用Visitor Pattern。