强制转换为多重继承

Cast to multiple inheritance

本文关键字:多重继承 转换      更新时间:2023-10-16

我想知道是否可以在不知道其初始类型的情况下将对象强制转换为它继承的多个类。例如,假设我有以下结构:

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。你会怎么解决这个问题?

我知道这样做可能是不安全的,而且可能是糟糕的设计,然而,我仍然有兴趣知道这是否可能。

您可以使用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]);

这使用运行时类型检查,如果v[0]不是从B派生的,则生成nullptr

至于struct Tmp,根据语言,它与Z根本没有关系,尽管有共同的基础。如果Tmp也声明了自己的成员呢?如果希望访问BC子对象,而不管它们是如何继承的,请使用两个单独的dynamic_cast操作获取引用。

您似乎不止一次使用AB(用于强制转换和创建Tmp结构。我建议您为struct X : A, B {...}命名一个有用的名称,并将Z定义为:struct Z : X, C, D {}

然后演员阵容变为:

X* tmp = static_cast<X*>(v[0]);
tmp->b = 6;
std::cout << zed->b << std::endl;