0

是否可以在运行时动态选择要转换的类型?

例如,假设我有:

ClassType * pointer=static_cast<ClassType*>(baseClassPointer);

但是,在运行时,我想选择它是什么ClassType,而不是将其硬编码到函数中。

这可能吗?我想我想使用它的两种方法是传递一个char *包含我要使用的类型名称的实际值,或者以某种方式从现有类中提取类型信息并将其用作强制转换。

我想这样做的原因是我有几个来自公共基类的派生类。我可以获得每个派生类的基类的基本功能,但是如果我想要一个指针来访问仅存在于派生类中的某些特定功能,我需要像这样转换该指针。而且我想要一个函数,允许我为任何派生类动态地进行这种转换。

4

4 回答 4

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 );

确保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% 肯定地说。

祝你好运!

于 2013-04-12T01:54:41.013 回答
1

即使您可以在运行时执行此操作(我认为您做不到),您将如何处理返回的派生类指针?您在编写代码时不知道会返回什么类型的对象,那么您怎么知道可以调用哪些方法呢?

我认为您最好将虚拟方法添加到您的基类以捕获必要的功能,或者您可以使用Visitor Pattern

于 2013-04-12T02:04:02.453 回答
1

坏设计被发现!重写你的派生类怎么样?你在搞一些非常危险的事情

于 2013-04-12T01:53:11.113 回答
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();
    }
}
于 2013-04-12T01:54:20.103 回答