多重虚继承C++

Multiple virtual inheritance C++

我在多重继承方面遇到了问题,如果有人能帮助我,那就太好了。我正在编写一个最终归结为类似于此的情况

    class A {
public:
    A(){}
    virtual ~A() = 0;
    virtual void print()=0;
};
A::~A(){}

class B: public virtual A {
public:
    B():A(){}
    virtual ~B() = 0;
    virtual void print() {
        cout << "Hello" << endl;
    }
};
B::~B(){}

class C: public virtual A {
public:
    C():A(){}
    virtual ~C() = 0;
    virtual void print () {
        cout << "Bye" << endl;
    }
};
C::~C(){}

class D: public B, public C {
public:
    D():B(),C(){}
    virtual ~D(){}
    virtual void print(){}
};

int main()
{
    D d;
    A* a = &d;
    a->B::print(); //The statement leads to errors
    a->C::print(); //The statement leads to errors
}

我需要访问 class B 和 class C 中虚函数的实现。有没有办法做到这一点?

类型 A 根本不知道子类 BC 中的实现。要调用这些成员,您首先必须将 a 转换为至少 BC,甚至转换为 D:

D* aAsD = dynamic_cast<D*>(a);
if (aAsD) {
    aAsD->B::print(); 
    aAsD->C::print();
}

A *a 不知道 BC 中的 print()。您可能希望 D 处理是否调用 B::print()C::print().

class D: public B, public C {
public:
    D():B(),C(){}
    virtual ~D(){}
    virtual void print()
    {
       B::print(); //or some logic to call one of them
       C::print();
    }    
};

D d;
A* a = &d;
a->print(); 

像那样做 B::Print 或 C::print 的整个愿望似乎有些不对......尤其是当你让它成为 D 中的空操作时。

这表明也许 D 不应该继承 B 和 C,而是包含一个 B 和一个 C。然后您可以将 B 和 C 与 D 分开公开,这可以作为 A 单独传递。

显然这可能不适用于您的扩展问题,但适用于您发布的问题;我会称之为继承滥用。

要理解这一点,请暂时忽略继承:

  1. Class 'A' 没有打印方法
  2. Class 'B'和'C'有自己的打印方式
  3. Class 'D'本身没有打印方法

现在将继承添加到等式中:

  1. Class'D'继承了'B'和'C',所以它有两种打印方式
  2. Class 'B'和'C'继承了'A',但是由于'A'没有打印方法,所以它们仍然有相同的方法
  3. Class 'A' 没有打印方法。

当您转换 A* a = &d 时,您正在将具有两种打印方法的 class 转换为没有打印方法的 class。由于继承的力量,'A' class 打印方法现在被 'D' class 中的方法重载,但 'a' 变量仍然是一个 'A' class(来自 'D' 的重载)。由于 'A' 不继承 'B' 或 'C',它不知道它们是什么。尝试使用它们时出现错误的原因。

解决这个问题的方法就是不将 'D' 转换为 'A':

int main() {
    D d;
    d.B::print(); //Hello
    d.C::print(); //Bye
}

此外,如果您需要将 'D' 转换为 'A',您应该将其相应地转换为 B 或 C:

int main() {
    D d;
    A* a = &d;
    dynamic_cast<B*>(a)->B::print();
    dynamic_cast<C*>(a)->C::print();
}

或 1 个动态转换版本:

int main() {
    D d;
    A* a = &d;
    D* dptr = dynamic_cast<D*>(a);
    dptr->B::print();
    dptr->C::print();
}

换句话说,在分别使用'C'和'B'之前,你必须将'a'向上转换为继承'C'和'B'的东西