在C+中重新解释多重继承中使用的强制转换+; 在做一些C++的过程中,我发现了一个有趣的例子,涉及到多继承和铸造。

在C+中重新解释多重继承中使用的强制转换+; 在做一些C++的过程中,我发现了一个有趣的例子,涉及到多继承和铸造。,c++,inheritance,casting,reinterpret-cast,C++,Inheritance,Casting,Reinterpret Cast,我不知道为什么 reinterpret\u cast(b1)不等于reinterpret\u cast(b2) 这是一个简单的程序,我在上面提到过: #include <iostream> class A { public: A() : m_i(0) { } protected: int m_i; }; class B { public: B() : m_d(0.0) { } protected: double m_d; }; class C

我不知道为什么
reinterpret\u cast(b1)不等于reinterpret\u cast(b2)

这是一个简单的程序,我在上面提到过:

#include <iostream>

class A
{
public:
    A() : m_i(0) { }

protected:
    int m_i;
};

class B
{
public:
    B() : m_d(0.0) { }

protected:
    double m_d;
};

class C
    : public A
    , public B
{
public:
    C() : m_c('a') { }

private:
    char m_c;
};

int main()
{
    C d;
    A *b1 = &d;
    B *b2 = &d;

    const int a = (reinterpret_cast<char*>(b1) == reinterpret_cast<char*>(&d)) ? 1 : 2;
    const int b = (b2 == &d) ? 3 : 4;
    const int c = (reinterpret_cast<char*>(b1) == reinterpret_cast<char*>(b2)) ? 5 : 6;

    std::cout << a << b << c << std::endl;

    return 0;
}
#包括
甲级
{
公众:
A():m_i(0){}
受保护的:
国际货币基金组织;
};
B类
{
公众:
B():mud(0.0){}
受保护的:
双m_d;
};
C类
:公众A
,公共图书馆
{
公众:
C():m_C('a'){}
私人:
charm_c;
};
int main()
{
cd;
A*b1=&d;
B*b2=&d;
常数INTA=(重新解释投射(b1)=重新解释投射(&d))?1:2;
常数INTB=(b2==&d)?3:4;
const int c=(重新解释投射(b1)=重新解释投射(b2))?5:6;

std::cout为什么地址应该相等?
*b1
A
类型的对象,
*b2
B
类型的对象。它们是不同的对象(尽管不是完整的对象)两个都不是另一个的子对象,所以它们应该有不同的地址——事实上,它们拥有相同地址的唯一方法是至少有一个类型为空(在代码中不是这样)

C---------------+
|A---+ B---+    |
||m_i| |m_d| m_c|
|+---+ +---+    |
+---------------+
这意味着
A
子对象与整个
C
对象在同一地址开始,但是
B
子对象被移动
A
的大小(即
int
的大小)

因为
b2
是指向
B
的指针,它指向
B
子对象,因此它指向的物理地址是移位的

至于为什么
b2==&d
保持不变-指向不同类型的指针永远无法进行相等比较。但是指向派生类的指针可以隐式转换为指向基类的指针。因此
b2==&d
实际上转换为
b2==static\u cast(&d)
,它保持不变。请注意,隐式转换自然会应用移位,它与您最初获得的
b2
相同


您可以尝试重新组织继承顺序或删除/添加一些数据成员,以了解其对布局的影响。

更改继承A和B的顺序,并检查结果。这是否有助于您了解发生的情况?好的,这听起来很合理,但如果是,为什么b2==&d为真,但重新解释(b2)==reinterpret_cast(&d)是假的吗?@Leopoldo:因为你的假设是假的;)具体来说,
b2=&d
不是
(void*)b2==(void*)和d
,而是将
&d
转换为
B*
,这将应用偏移量,然后才与
b2==static_cast(&d)进行比较
@Leopoldo我已经扩展了答案。
B *b2 = &d;