将类型名称动态传递给static_cast

时间:2013-04-12 01:48:04

标签: c++

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

例如,假设我有:

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

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

这可能吗?我想要使​​用它的两种方式是传递包含我想要使用的类型名称的实际char *,或以某种方式从现有类中提取类型信息并将其用作演员。

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

4 个答案:

答案 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