【问题标题】:dynamic_cast vs static_cast to void*dynamic_cast 与 static_cast 到 void*
【发布时间】:2014-05-29 07:18:48
【问题描述】:

在下面程序的最后两行中,static_cast<void*> 和 dynamic_cast<void *> 的行为不同。据我了解,dynamic_cast<void*> 的结果始终解析为完整对象的地址。所以它以某种方式使用 RTTI。谁能解释编译器如何使用 RTTI 来区分两者。

#include <iostream>
using namespace std;
class Top {
protected:
int x;
public:
    Top(int n) { x = n; }
    virtual ~Top() {} 
    friend ostream& operator<<(ostream& os, const Top& t) {
        return os << t.x;
    }
};
class Left : virtual public Top {
protected:
    int y;
public:
    Left(int m, int n) : Top(m) { y = n; }
};
class Right : virtual public Top {
protected:
    int z;
public:
    Right(int m, int n) : Top(m) { z = n; }
};
class Bottom : public Left, public Right {
    int w; 
public:
    Bottom(int i, int j, int k, int m): Top(i), Left(0, j), Right(0, k) { w = m; }
    friend ostream& operator<<(ostream& os, const Bottom& b) {
        return os << b.x << ',' << b.y << ',' << b.z<< ',' << b.w;
    }
};
int main() {
    Bottom b(1, 2, 3, 4);
    cout << sizeof b << endl;
    cout << b << endl;
    cout << static_cast<void*>(&b) << endl;
    Top* p = static_cast<Top*>(&b);
    cout << *p << endl;
    cout << p << endl;
    cout << static_cast<void*>(p) << endl;
    cout << dynamic_cast<void*>(p) << endl;
    return 0;
}

可能的输出:https://ideone.com/WoX5DI

28
1,2,3,4
0xbfcce604
1
0xbfcce618
0xbfcce618
0xbfcce604

【问题讨论】:

  • 动态转换为void* 的工作方式与动态转换为派生类指针的方式相同。在典型的实现中,它查找指针指向的对象的 vptr 并使用它来确定最派生对象的类型。然后可以相应地计算偏移量。
  • @Brian 在 void* 情况下这是不可能的
  • dynamic_cast&lt;void*&gt; - 这样做有意义吗?执行此操作的每个代码都应该通过任何体面的审查。
  • @BЈовић: dynamic_cast 到 void * 是 dynamic_cast 的一个专用的、特定的功能,这是故意设计的。我从未在实践中使用过它,但显然有人认为它具有实际意义。

标签: c++ casting void-pointers dynamic-cast


【解决方案1】:

从 5.2.7 / 7:

如果 T 是“指向 cv void 的指针”,那么结果是指向最 v 指向的派生对象。否则,应用运行时检查 查看 v 指向或引用的对象是否可以转换为 T 指向或引用的类型。

因此,使用dynamic_cast&lt;void*&gt;(o),您将获得一个指向最“派生”对象的第一个字节的指针(如果o 是多态的)。

编译器为dynamic_cast&lt;void *&gt;(...) 生成的代码类似于:

static_cast<void*>(dynamic_cast<most_derived_type *>(...))

该属性常用于序列化。

【讨论】:

  • C++ 充满惊喜。
  • 这对于建立对象身份的指针比较(也)很有用,尤其是当存在(非virtual)菱形继承时。
猜你喜欢
  • 2011-06-06
  • 1970-01-01
  • 2010-11-18
  • 1970-01-01
  • 1970-01-01
  • 2011-10-31
  • 2010-09-06
相关资源
最近更新 更多