如何确定dynamic_cast到哪种类型?

时间:2014-04-07 22:12:25

标签: c++ dynamic-cast

我一直在阅读dynamic_cast上有关我正在研究的程序的教程,而且我还没有完全掌握如何利用它。

我有多个方法可以传递超类指针的参数,并从那里区分哪个方法来确定要进行哪些操作。

例如,超类可能是Value,子类是RationalNumber

我的计划是为int设置RationalNumber值ID,我不知道,1,然后当我使用dynamic_cast时,它将确定{ {1}}对象实际上是Value*,将执行操作。

我如何实现这个目标?

3 个答案:

答案 0 :(得分:2)

典型示例:

class Value
{
 public:
   virtual ~Value();
};

class RationalNumber : public Value
{
  ... 
}


Value *v = new RationalNumber(...)


... 
RationalNumber* test = dynamic_cast<RationalNumber*>(v);

if (v)
   cout << "v is a rational number" << endl;
else
   cout << "v is a not rational number" << endl;

但请注意,在几乎所有具有继承的情况下,这都不是一个好的解决方案。我正在编写一个编译器,这是我第一次使用dynamic_cast - 主要是因为有一些相当通用的函数可以处理(例如){{1}类指针,并将所有派生类(当前计数的31个类)的函数的所有变量添加到ExprAST中将是相当不实用的。 (当然,拨打ExprAST的电话并不比expr->isVariableExprAST()好得多 - 它的代码数量相同,或多或少。

但在大多数情况下,不知道你处理的是哪种类型是一个更好的解决方案。

更合适的解决方案是使用对所有类都通用的虚函数,例如:

VariableExprAST* var = dynamic_cast<VariableExprAST*>(expr); if (var) ...

在这种情况下,您不需要执行任何检查 - 您只需要为所有子类型实现方法class Value { public: virtual ~Value(); virtual void SomeMethod() = 0; }; class RationalNumber : public Value { ... virtual void SomeMethod() { ... } } class IrrationalNumber : public Value { ... virtual void SomeMethod() { ... } } Value *v = ... v->SomeMethod();

答案 1 :(得分:2)

dynamic_cast运算符根据对象的V-Table指针(当您有一个或多个时添加到对象类中的隐式成员字段)的值来确定运行时对象的类型该类中的虚函数。)

这里没有什么可以实现的,您可以简单地调用它。例如:

bool isRationalNumber(Value* object)
{
    RationalNumber* number = dynamic_cast<RationalNumber*>(object);
    if (number == NULL)
        return false;
    return true;
}

请注意,您不能在未声明至少一个虚拟函数的类上使用它,因为此类没有V-Table。

此外,在某些编译器上,您需要在项目设置中启用RTTI。

最后 - 一个小小的建议(更多的是个人观点,所以你可以选择忽略它):

动态强制转换与多态性概念形成鲜明对比,在多态性概念中,您可以在单个基类下概括具有公共属性的对象,然后使用泛型基类引用它们。使用动态强制转换,您实际上正好相反,因为您在决定要采取的操作之前检查对象的特定类型。

所以建议是,尽量避免使用它。

如果您发现自己没有其他选择,请检查您的设计。

答案 2 :(得分:0)

标准方法是dynamic_cast派生类的对象,然后测试结果是否为null。例如(使用您的术语):

void method(SuperClass* object) {

  SubClass* subclass = dynamic_cast<SubClass*>(object);

  if (subclass) {
    // the object is a 'SubClass'
    // do stuff...
  }

}

如果您有多个子类,则必须单独检查它们。 E.g:

void method(SuperClass* object) {

  SubClass_1* subclass_1 = dynamic_cast<SubClass_1*>(object);
  if (subclass_1) {
    // the object is a 'SubClass_1'
    // do stuff...
    return;
  }

  SubClass_2* subclass_2 = dynamic_cast<SubClass_2*>(object);
  if (subclass_2) {
    // the object is a 'SubClass_2'
    // do stuff...
    return;
  }


}