dynamic_cast的VS的static_cast为void*

cla*_*ius 8 c++ dynamic-cast casting void-pointers

在最后两行以下程序,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;
}
Run Code Online (Sandbox Code Playgroud)

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

28
1,2,3,4
0xbfcce604
1
0xbfcce618
0xbfcce618
0xbfcce604
Run Code Online (Sandbox Code Playgroud)

man*_*lio 9

从5.2.7/7:

如果T是"指向cv void的指针",则结果是指向v所指向的最派生对象的指针.否则,将应用运行时检查以查看v指向或引用的对象是否可以转换为尖的或由T.所指类型

因此,使用dynamic_cast<void*>(o)你的指针最"派生"对象的第一个字节(如果o是多态).

编译器生成的代码dynamic_cast<void *>(...)是一样的东西:

static_cast<void*>(dynamic_cast<most_derived_type *>(...))
Run Code Online (Sandbox Code Playgroud)

此属性通常用于序列化.

  • C++充满了惊喜. (3认同)