Question

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;
}
Was it helpful?

Solution

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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top