指向层次结构中类的指针的相等性

时间:2014-10-20 14:16:00

标签: c++ class pointers inheritance memory-address

#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 c;
    A *pa = &c;
    B *pb = &c;

    const int x = (pa == &c) ? 1 : 2;
    const int y = (pb == &c) ? 3 : 4;
    const int z = (reinterpret_cast<char*>(pa) == reinterpret_cast<char*>(pb)) ? 5 : 6;

    std::cout << x << y << z << std::endl;

    return 0;
}

此代码打印出136,这表示第一个等式为真,第二个也不是第三个。由于papb都设置为&c,前两个会有意义,但为什么第三个等式会为假?

我在Visual C ++ 2012中运行此代码,并使用调试器检查地址:

pa == 0x003bfc90
pb == 0x003bfc98
&c == 0x003bfc90

显然,papb并未指向相同的地址,这意味着第三个等式应为假(并且是)。但那么为什么前两个是真的呢?你能解释一下这里发生了什么吗?

1 个答案:

答案 0 :(得分:7)

两个指针确实具有不同的值,因为它们指向c的不同子对象;这两个对象必须存在于不同的位置。

如果没有reinterpret_cast,则相等比较首先查找到相同指针类型的合适转换。这会将&cC*转换为B*,方法是修改指针值以指向B的{​​{1}}子对象 - 与应用的转换完全相同在初始化c时。在转换之后,两个指针都具有相同的值,因此比较相等。

pb表示指针应转换为目标类型而不修改其值,无论该转换是否有意义。因此,在转换之后,指针仍然具有不同的值,并且比较不相等。