地址,reinterpret_cast和多重继承

时间:2012-09-20 11:54:11

标签: c++ pointers multiple-inheritance reinterpret-cast

有人可以解释以下代码的行为吗?

  1. 为什么我们在第一种情况下有b = 3,即b2 == &d是真的?
  2. 为什么在案例2中没问题?我打印了b2d的地址,它们是不同的。
  3. #include <iostream>
    
    using namespace std;
    
    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;
        B *b2 = &d;
    
        cout << &d << endl;
        cout << b2 << endl;
    
        const int b = (b2 == &d) ? 3 : 4; ///Case1: b = 3;
        const int c = (reinterpret_cast<char*>(b2) == reinterpret_cast<char*>(&d)) ? 3 : 4; //Case 2:  c = 4;
    
        std::cout  << b << c << std::endl;
    
        return 0;
    }
    

2 个答案:

答案 0 :(得分:9)

d是C类型。当你将指向C的指针转换为指向B的指针时,它会被调整,使它指向C的B子对象(如果不需要,那么通常需要这样的ajustement具有多个继承性对于B,将有一个用于A,因为C继承自A和B)。因此,在分配和比较时,完成调整。

在另外两次,&amp; d被转换为void *(隐式)或char *(带有reinterpret_cast)并且没有进行任何调整(你明确要求使用reinterpret_cast进行调整,没有理由在转换为void *时进行调整,它只会使往返复杂化,没有充分的理由,你再次得到类似的结果A)所以表示不同。

顺便说一下,如果您使用过reinterpret_cast<B*>(&d),则不会再次进行调整,但将结果用作B *会导致问题迅速发生。

答案 1 :(得分:3)

在情况1中,比较自动将C指针强制转换为B指针。在这种情况下,这意味着实际地址会发生变化,因为您使用了多重继承,而B在基类列表中排名第二。更具体地说,指针必须偏移(至少)sizeof(A)。然而,在第二种情况下,没有执行这样的自动转换,因此“A前缀”使得两个指针不相等。