Can anybody explain the behaviour of the following code?

  1. Why do we have b = 3 in the first case, i.e. b2 == &d is true?
  2. Why is it ok in Case 2? I have printed the addresses of b2 and d, and they are different.
#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;
}
有帮助吗?

解决方案

d is of type C. When you convert a pointer to C to a pointer to B, it is adjusted so that it points to the B subobject of C (such ajustement is needed in general with multiple inheritence, if none was needed for B, there would be one for A as C inherit from both A and B). Thus at the assignation and comparison time, the adjustment is done.

At the two other times, &d is converted to either void* (implicitly) or char* (with a reinterpret_cast) and no adjustment is done (you asked explicitly for no adjustment with the reinterpret_cast and there is no reason to do an adjustment when converting to void*, it would just complicate the round trip for no good reason, you'd again have an similar result for A) so the representation is different.

BTW, if you had used reinterpret_cast<B*>(&d), no adjustment would have been made again, but using the result as a B* would have lead rapidly to problems.

其他提示

In case 1, the comparison automatically casts the C pointer to a B pointer. In this case, this means that the actual address changes, since you use multiple inheritance and B is second in your list of base-classes. To be more specific, the pointer has to be offset by (at least) sizeof(A). In the second case, however, no such automatic conversion is performed, so the "A prefix" makes the two pointers unequal.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top