views:

78

answers:

3

How do I access overridden members of base classes of base classes?

#include <iostream>
using namespace std;

class A {public: char x; A(){x='A';};};
class B1 : public A {public: char x; B1(){x='B';};};
class B2 : public A {public: char x; B2(){x='B';};};
class C : public B1, public B2 {public: char x; C(){x='C';};};

int main(){
    C c;
    cout << c.x << endl; // prints C

    cout << c.B1::x << endl; // prints B
    cout << ((B1&) c).x << endl; // prints B

    // cout << c.A::x << endl; // normally prints A but doesn't work here
    cout << ((A&) c).x << endl; // prints A
    return 0;
}

Is the reference (or pointer) way the only possibility? I tried A::B::x in order to chain scope operators, but that doesn't work. Suppose i want to keep the "double A", i.e. not make the inheritance virtual.

((B&) c).x seems to be a good "workaround" to c.B::x but they aren't equal in case of virtual functions, are they?

+1  A: 
c.A::x
KennyTM
Yeah ok...The problem came up with multiple inheritance... I thought it could be simplified by just multiple levels of inheritance but in fact the problem vanishes than. thx for pointing that out :-)- op edited
spc-mrn
+1  A: 

You can access both version of A via reference casts plus the scoping operator, likes this: ((B1&) c).A::x and ((B2&) c).A::x.

cout << ((A&) c).x << endl; fails on my compiler because the compiler doesn't know which copy of A's data you want to operate on.

Walter Mundt
Good - combining reference cast and scope op seems to be solving all problems. I'll accept that if no one comes up with another problem ...
spc-mrn
A: 

It won't work and the compiler should tell you why. At least mine does :-) : "A ambigous base for C". The answer is virtual inheritance

#include <iostream>
using namespace std;

class A {public: char x; A(){x='A';};};
class B1 : public virtual A {public: char x; B1(){x='B';};};
class B2 : public virtual A {public: char x; B2(){x='B';};};
class C : public B1, public B2 {public: char x; C(){x='C';};};

int main(){
    C c;
    cout << c.x << endl; // prints C

    cout << c.B1::x << endl; // prints B
    cout << ((B1&) c).x << endl; // prints B

    cout << c.A::x << endl; // normally prints A but doesn't work here
    //cout << ((A&) c).x << endl; // prints A
    return 0;
}
celavek
I wanted to keep every B's A seperate. THX anyways.
spc-mrn
You did not specify that in the question. And may I ask why you want them kept separately?
celavek
Actually you did! I guess I should have been more careful in reading the question.
celavek
Never mind - I could make up an example out of thin air. But the question came up from a theoretical pov.
spc-mrn