Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 动态\u强制转换与静态\u强制转换为无效*_C++_Casting_Void Pointers_Dynamic Cast - Fatal编程技术网

C++ 动态\u强制转换与静态\u强制转换为无效*

C++ 动态\u强制转换与静态\u强制转换为无效*,c++,casting,void-pointers,dynamic-cast,C++,Casting,Void Pointers,Dynamic Cast,在下面程序的最后两行中,static\u cast和dynamic\u cast的行为不同。据我所知,dynamic_cast的结果总是解析为完整对象的地址。所以它在某种程度上使用了RTTI。有谁能解释一下编译器是如何使用RTTI来区分两者的 #include <iostream> using namespace std; class Top { protected: int x; public: Top(int n) { x = n; } virtual ~Top(

在下面程序的最后两行中,
static\u cast
dynamic\u cast
的行为不同。据我所知,
dynamic_cast
的结果总是解析为完整对象的地址。所以它在某种程度上使用了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;
}
从5.2.7/7开始:

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

因此,使用
dynamic\u cast(o)
可以获得指向最“派生”对象的第一个字节的指针(如果
o
是多态的)

编译器为
dynamic_cast(…)
生成的代码如下:

static_cast<void*>(dynamic_cast<most_derived_type *>(...))
static_cast(动态_cast(…))

此属性通常用于序列化。

动态转换到
void*
的工作方式与动态转换到派生类指针的工作方式相同。在典型的实现中,它会查找指针指向的对象的vptr,并使用它来确定最派生对象的类型。然后可以相应地计算偏移量。@Brian在void*情况下这是不可能的
动态\u cast
-这样做有意义吗?每一个这样做的代码都应该没有通过任何适当的审查。@Bぃ:
dynamic_-cast
to
void*
dynamic_-cast
的一个专门的、特定的功能,是专门设计的。我在实践中从未使用过它,但显然有人认为它是实用的。C++是充满惊奇的。这对于指针比较来建立对象标识也是有用的,尤其是当有(非-Cuth>虚拟< /代码>)菱形继承时。
static_cast<void*>(dynamic_cast<most_derived_type *>(...))