【问题标题】:dynamic_cast of void *void 的 dynamic_cast *
【发布时间】:2011-10-09 23:06:38
【问题描述】:

我需要使用动态转换 void*

void *target = (MYClass*)target;//I am storing initially(to implment delegate mechanism)
....
delegateClass *delegate = dynamic_cast<delegateClass*>(target);

它给出错误 cannot convert void*,我不能使用下面的代码...因为它是一个委托机制

delegateClass *delegate = dynamic_cast<delegateClass*>(((MYClass*))target);

如何获取目标的类型并实现...如果我使用 typeid(),我可以获得类的名称,但如何在上面的等式中使用 typeid 而不是 (((MYClass*))target)。

【问题讨论】:

    标签: c++


    【解决方案1】:

    除非变量的原始类型具有 vtable(即具有虚函数),否则您不能使用动态转换。这是因为 dynamic_cast 需要运行时类型信息,这些信息记录在 vtable 中;如果 vtable 丢失,编译器不知道对象是什么类型。

    您应该使用虚拟析构函数声明基类,并使用指向该基类的指针而不是void *

    【讨论】:

    • 好主意...我创建了一个简单的根类(包含虚拟析构函数),而不是 void* 我使用了 CRoot*... 所以任何需要获得委托的类都必须是继承自 CRoot。
    【解决方案2】:

    如果您必须将对象作为void * 传递,那么您应该使用

    delegateClass *delegate = static_cast<delegateClass*>(((MYClass*))target);
    

    因为void *targetdelegateClass 之间没有类关系。在这里你是说你知道目标_is_a_delegateClass。

    然而,这个习惯用法通常用于通过标准 C 接口传递代码并返回。

    【讨论】:

      【解决方案3】:

      我处于类似情况并且正在学习 c++ 样式类型转换。我提到了这个链接http://www.cplusplus.com/doc/tutorial/typecasting/

      由此我可以解释的是,dynamic_cast 的目的是确保类型转换的结果是所请求类的有效完整对象。因此,当我们尝试从派生类转换为基类时,转换是平滑的。但反之亦然。

      class CBase { };
      class CDerived: public CBase { };
      
      CBase b; CBase* pb;
      CDerived d; CDerived* pd;
      
      pb = dynamic_cast<CBase*>(&d);     // ok: derived-to-base
      pd = dynamic_cast<CDerived*>(&b);  // wrong: base-to-derived 
      

      现在要让它工作,基类应该是多态的,即它应该有一个虚函数。当类是多态的时,dynamic_cast 在运行时执行特殊检查,以确保表达式产生所请求类的有效完整对象。看看这里。

      class CBase { virtual void dummy() {} };
      class CDerived: public CBase { int a; };
      
      int main () {
        try {
          CBase * pba = new CDerived;
          CBase * pbb = new CBase;
          CDerived * pd;
      
          pd = dynamic_cast<CDerived*>(pba);
          if (pd==0) cout << "Null pointer on first type-cast" << endl;
      
          pd = dynamic_cast<CDerived*>(pbb);
          if (pd==0) cout << "Null pointer on second type-cast" << endl;
      
        } catch (exception& e) {cout << "Exception: " << e.what();}
        return 0;
      }
      

      这里的代码尝试执行从 CBase* 类型的指针对象(pba 和 pbb)到 CDerived* 类型的指针对象的两次动态转换,但只有第一个成功。尽管两者都是 CBase* 类型的指针,pba 指向 CDerived 类型的对象,而 pbb 指向 CBase 类型的对象。因此,当使用 dynamic_cast 执行它们各自的类型转换时,pba 指向 CDerived 类的完整对象,而 pbb 指向 CBase 类的对象,它是 CDerived 类的不完整对象,因此它返回一个指向指出失败。

      所以我建议您使用提供双向类型转换的 static_cast,即从派生到基类以及从派生到基类。但在这种情况下,程序员需要确保转换是安全的,因为类型检查不像 dynamic_cast 那样在运行时执行。

      在您的代码中,要么在转换之前将目标指向 deligate 类对象(但确保 Myclass 是多态的),否则您可以使用 static_cast。

      此解释基于我最近对该主题的阅读,我建议您参考 Effective C++ 以获得更多信息。我希望这将有所帮助。 :)

      【讨论】:

        猜你喜欢
        • 2011-05-07
        • 2014-05-29
        • 2011-03-10
        • 2014-10-25
        • 2012-03-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多