c++ - C++中多继承中使用的reinterpret_cast

标签 c++ inheritance casting reinterpret-cast

在做一些 C++ 练习时,我发现了一个与多重继承和转换相关的有趣示例。

我想不通为什么 reinterpret_cast<char*>(b1) is not equal reinterpret_cast<char*>(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;
}

当 reinterpret_cast(b1) 等于 reinterpret_cast(&d) 时,您能否对这个主题提供任何评论以帮助我弄清楚为什么 reinterpret_cast(b1) 不等于 reinterpret_cast(b2)?

最佳答案

基类子对象必须以某种方式排列在最派生对象的内存中。在您的情况下,编译器似乎是这样做的:

C---------------+
|A---+ B---+    |
||m_i| |m_d| m_c|
|+---+ +---+    |
+---------------+

这意味着 A子对象的起始地址与整个 C 相同对象,但是 B子对象移动了 A 的大小(即 int 的大小)。

B *b2 = &d;

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

至于为什么b2 == &d持有 - 指向不同类型的指针永远无法比较是否相等。但是指向派生类的指针可以隐式转换为指向基类的指针。所以b2 == &d实际上转换为b2 == static_cast<B*>(&d) ,它成立。请注意,隐式转换自然会应用移位,它与您用来获取 b2 的相同。首先。

您可以尝试重新组织继承顺序或删除/添加一些数据成员以查看它如何影响布局。

关于c++ - C++中多继承中使用的reinterpret_cast,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23405851/

相关文章:

python - 在没有科学记数法的情况下将 float 转换为字符串

c++ - 如何根据 libxml++ 中的 relaxNG 模式验证 xml 文档

c++ - C++ 中的继承成本

java - 如何扩展 OHLCItem 类并在 OHLCSeries 中使用它

ios - 多重继承问题Swift

C++ fread() 到 std::string

c++ - 我不明白这些编译错误

具有模板接口(interface)的 C++ 多态性

c++ - 检查(原始)类型在 C++ 中是否可转换

c++ - DWORD 在 LPVOID 上的类型转换返回什么?