Reputation: 187
I would like to know if it is possible to cast an object to multiple classes that it inherits from without knowing its initial type. For example, suppose I have the following structs:
struct A {
int a;
};
struct B {
int b;
};
struct C {
int c;
};
struct D {
int d;
};
struct Z : A, B, C, D {};
And I add instances of Z to a vector.
vector<A *> v;
Z *zed = new Z();
v.push_back(zed);
Now suppose that I know that the first element in the vector inherits from A and B and I would like to cast it to A and B.
struct Tmp : A, B {};
Tmp *tmp = static_cast<Tmp *>(v[0]);
tmp->b = 6;
cout << zed->b << endl;
However, doing this causes issues. Mainly if Z was instead defined as struct Z : A, C, D, B {};
then cout << zed->b << endl;
would print 0 and not 6. How would you get around this?
I understand that doing this is potentially unsafe and probably poor design, however, i'm still interested in knowing if it's possible.
Upvotes: 0
Views: 102
Reputation: 137810
You can use dynamic_cast
to go "across" the inheritance hierarchy. But there needs to be at least one virtual function in the "from" type, and you can't cast from a virtual or multiply-inherited base.
struct A {
int a;
virtual ~A() {}
};
struct Z : A, B, C, D {};
vector<A *> v;
Z *zed = new Z();
v.push_back(zed);
B *tmp = dynamic_cast<B *>(v[0]);
This uses runtime type inspection and yields nullptr
if v[0]
wasn't derived from B
after all.
As for struct Tmp
, according to the language it's not related to Z
at all despite having common bases. What if Tmp
also declared its own members? If you want access to the B
and C
subobjects regardless of how they were inherited, get references using two separate dynamic_cast
operations.
Upvotes: 1
Reputation: 76240
You seem to be using A
and B
more than once there (both to cast and to create the Tmp
struct. I'd suggest you to give an useful name to struct X : A, B {...}
and define Z
as: struct Z : X, C, D {}
.
Then the cast becomes:
X* tmp = static_cast<X*>(v[0]);
tmp->b = 6;
std::cout << zed->b << std::endl;
Upvotes: 0