Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
多重虚拟继承C++_C++_Multiple Inheritance_Diamond Problem - Fatal编程技术网

多重虚拟继承C++

多重虚拟继承C++,c++,multiple-inheritance,diamond-problem,C++,Multiple Inheritance,Diamond Problem,我有一个多重继承的问题,如果有人能帮助我,那就太好了。我正在规划一个最终可以归结为类似的情况 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() {

我有一个多重继承的问题,如果有人能帮助我,那就太好了。我正在规划一个最终可以归结为类似的情况

    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
}
我需要访问类B和类C中虚拟函数的实现。有什么方法可以做到这一点吗

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

A*A不知道在B或C中打印。您可能希望D处理是调用B::print还是C::print


像这样做B::Print或C::Print的整个愿望似乎有点不对劲。。。尤其是当你把它变成D区的禁区

它建议D不应该继承B和C,而是包含a和B。然后你可以将B和C与D分开,D可以作为a单独传递


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

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

类“A”没有打印方法 “B”类和“C”类有自己的打印方法 类“D”本身没有打印方法。 现在将继承添加到等式中:

类“D”继承了“B”和“C”,因此它同时具有两种打印方法 类“B”和“C”继承了“A”,但由于“A”没有打印方法,它们仍然具有相同的方法 类“A”没有打印方法。 当您强制转换A*A=&d时,您正在将具有两个打印方法的类转换为不具有打印方法的类。由于继承的强大功能,“A”类打印方法现在被“D”类中的方法重载,但“A”变量仍然是一个“A”类,重载来自“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”的内容;修复了这个问题。你能给B版本一个别名或者你可以调用的替代名称吗?可能是Hi@maxim的重复,实际上继承链相当大,A实际上是从一堆其他类继承的。我想从上层阶级动态地分派打印的执行,而不是有一个指向D的指针,这会杀死分派。不幸的是,在我的情况下,dynamic_cast不是一个有吸引力的解决方案,因为我的目标是嵌入式系统Showever,静态_cast可能仍然是allowed@RaghurajTarikere当我用C++做了一些嵌入式编程时,C++的某些特性被编译器开关禁用了。我们无法使用RTTI、异常、虚拟多态性或流。为了构建您拥有的某种类型的结构,我们将使用包含函数和成员函数,这些函数将发送thunk到正确的成员对象。听起来你可以使用所有的C++,但这项技术可能会帮助你考虑。比嵌入式系统动态浇铸更好地重新解释铸件。一个指向B或C的指针,然后调用它们上的函数对我来说是很好的。但它仍然使最终的代码不可移植,这有点关系。如果不使用指针,就无法访问“B”或“C”打印方法。你可以,强硬,访问所有的“D”方法。您不能在D中创建一个方法,相应地打印“B”或“C”吗?可能使用枚举作为参数
int main() {
    D d;
    d.B::print(); //Hello
    d.C::print(); //Bye
}
int main() {
    D d;
    A* a = &d;
    dynamic_cast<B*>(a)->B::print();
    dynamic_cast<C*>(a)->C::print();
}
int main() {
    D d;
    A* a = &d;
    D* dptr = dynamic_cast<D*>(a);
    dptr->B::print();
    dptr->C::print();
}