多重虚拟继承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();
}