You can maybe use the fact, that when you make a cast from a pointer to a base class, that is not the only base class, the compiler will adjust the pointer so that it will point to the beginning of the super class. Therefore, if your "c" member would exist at the beginning of some base class, you could do a trick like:
struct myStructBase1 { int a; };
struct myStructBase2 { int b; };
struct myStructBase3 { int c; };
struct myStruct : public myStructBase1,myStructBase2,myStructBase3 {
int d;
};
int main() {
myStruct my;
int * bptr = &my.b;
int * cptr = &my.c;
// The only dirty part in the code...
myStructBase2 * base2ptr = reinterpret_cast<myStructBase2*> (bptr);
myStructBase3 * base3ptr = reinterpret_cast<myStructBase3*> (cptr);
// In each (myStruct*) cast the pointers are adjusted to point to the super class.
cout << &my << endl <<
(myStruct*) base2ptr << endl <<
(myStruct*) base3ptr << endl;
return 0;
}
// Output:
// 0xbfbc779c
// 0xbfbc779c
// 0xbfbc779c
The requirement for this to work is: if a member is the first member in its class, then its address in a object is equal to address of the object (of that class). I'm not sure if this is true.
EDIT: it should hold when the wrapper-base classes will be PODs. After following modifications:
struct myStructBase1 { int a; virtual void g() {} };
struct myStructBase2 { int b; virtual void f() {} };
struct myStructBase3 { int c; };
struct myStruct : public myStructBase1,myStructBase2,myStructBase3 {
int d;
virtual void h() {}
};
The output is:
0xbfa305f4
0xbfa305f8
0xbfa305f4
For the c member, the constraint still holds. So generally the answer is: yes, there is an alternative way. However, defining a base class for each "reversible"-member is probably not wise way..