我想知道是否可以将对象转换为它继承的多个类而不知道它的初始类型。例如,假设我有以下结构:
struct A {
int a;
};
struct B {
int b;
};
struct C {
int c;
};
struct D {
int d;
};
struct Z : A, B, C, D {};
我将Z的实例添加到矢量中。
vector<A *> v;
Z *zed = new Z();
v.push_back(zed);
现在假设我知道向量中的第一个元素继承自A和B,我想把它转换为A和B.
struct Tmp : A, B {};
Tmp *tmp = static_cast<Tmp *>(v[0]);
tmp->b = 6;
cout << zed->b << endl;
然而,这样做会导致问题。主要是如果Z被定义为struct Z : A, C, D, B {};
,那么cout << zed->b << endl;
将打印0而不是6.你会如何解决这个问题?
我知道这样做可能不安全,可能设计不佳,但是,我仍然有兴趣知道它是否可行。
答案 0 :(得分:1)
您可以使用dynamic_cast
跨越继承层次结构。但是,“from”类型中至少需要有一个虚函数,并且不能从虚拟或多重继承的基础转换。
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]);
这使用运行时类型检查,如果nullptr
毕竟不是v[0]
,则会产生B
。
至于struct Tmp
,根据语言,尽管有共同的基础,它根本与Z
无关。如果Tmp
也宣布自己的成员怎么办?如果您想要访问B
和C
子对象而不管它们是如何继承的,请使用两个单独的dynamic_cast
操作来获取引用。
答案 1 :(得分:0)
您似乎不止一次地使用A
和B
(两者都用于转换和创建Tmp
结构。我建议您为{{{}}提供一个有用的名称{1}}并将struct X : A, B {...}
定义为:Z
。
然后演员变为:
struct Z : X, C, D {}