velis
velis

Reputation: 10035

Why does this work? (multiple inheritance, slicing)

Consider this example:

#include <iostream>
using namespace std;

class A
{
public:
    int x;
};

class B
{
public:
    int y;
    B() { y = 0; }
    B(int var): y(var) {}
};

class C : public A, public B
{
public:
    void assignB(B x)
    {
        *(B *)this = x;  // <-- why does this properly assign B?
    }
};

int main() {
    C test;
    test.x = 5;
    test.y = 10;
    test.assignB(B(2));
    cout << "x " << test.x << endl;
    cout << "y " << test.y << endl;
    return 0;
}

What I'm curious about is the assignB method of class C. Normally, what I'd expect with typecasting is that the (B *) this would typecast this to B* and consequently overwrite x member, not y as it does. However, this code does exactly the opposite: it properly? assigns to the B part of C.

Just tested on MSVC 2013 and GCC 4.9.2. Both behaving the same.

Upvotes: 2

Views: 440

Answers (1)

onqtam
onqtam

Reputation: 4538

This is because the pointer is adjusted because of the multiple inheritance.

If you print the address this would be obvious

cout << (long long int)(this) << endl;
cout << (long long int)((B *)this) << endl;

Also consider using static_cast. In this case plain C style cast works as well though.

Upvotes: 2

Related Questions