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

Equality of pointers to classes in hierarchy

本文关键字:指针 层次结构      更新时间:2023-10-16
#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没有指向同一个地址,这意味着第三个等式应该是假的(确实如此(。但是,为什么前两个是真的呢?你能给我解释一下这是怎么回事吗?

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

如果没有reinterpret_cast,相等比较首先寻找一个合适的转换到相同的指针类型。这将&cC*转换为B*,方法是修改指针值以指向cB子对象 - 与初始化pb时应用的转换完全相同。转换后,两个指针具有相同的值,因此比较相等。

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