我很难解决可怕的钻石问题。提醒一下,这里是这个问题的经典类层次结构:
B
/ \
C1 C2
\ /
D
为了解决这个问题,标准的解决方案是让 C1 和 C2 使用虚拟继承从 B 继承。
我的问题是 B 和 C1 来自我无法修改的 SDK。 下面的示例我无法让SubClassB虚拟地从Base继承。类:PureVirtualBase、Base 和 SubClassB 来自我使用的 SDK。我无法修改它们。SubClassA 和 Leaf 是我的自定义类。我可以改变它们。
PureVirtualBase(SDK)
|
Base(SDK)
/ \
SubClassA SubClassB(SDK)
\ /
Leaf
在这种情况下,无法将SubClassB更改为使用来自Base的虚拟继承。应该怎么做:
- Leaf实例只包含一个Base
- 在尝试访问在PureVirtualBase中定义的纯虚拟函数并在Base中实现时避免歧义
class PureVirtualBase
{
public:
PureVirtualBase()
{
cout<<"<<PureVirtualBase::PureVirtualBase" << endl;
cout<<">>PureVirtualBase::PureVirtualBase" << endl;
}
virtual int f_PureVirtualBase()=0;
};
class Base : public PureVirtualBase
{
public:
Base(std::string id) {
cout<<"<<Base::Base:"<<id << endl;
m_id=id;
cout<<">>Base::Base:"<<m_id << endl;
}
virtual int f_PureVirtualBase() {
cout<<"Base::f_PureVirtualBase" << endl;
return 1;
}
private:
std::string m_id;
};
class SubClassA: public virtual Base
{
public:
SubClassA(): Base("From SubClassA") {
cout<<"<<SubClassA::SubClassA" << endl;
cout<<">>SubClassA::SubClassA" << endl;
}
};
class SubClassB: public Base
{
public:
SubClassB():Base("From SubClassB") {
cout<<"<<SubClassB::SubClassB" << endl;
cout<<">>SubClassB::SubClassB" << endl;
}
};
class Leaf: public SubClassA, public SubClassB
{
public:
Leaf():SubClassA(), SubClassB(), Base("From Leaf") {
cout << "<<Leaf::Leaf" << endl;
cout << ">>Leaf::Leaf"<< endl;
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Leaf myleaf;
myleaf.f_PureVirtualBase();
return a.exec();
}
- 如果我评论对 f_PurevirtualBase 的调用,它会编译,但我有一个警告, 由于模棱两可,'Leaf' 中的虚拟基础'Base' 不可访问如果我取消注释此调用:我收到此错误:对成员'f_PureVirtualBase' 的请求不明确
- 如果我在这个调用前面加上类名(myleaf.SubClassA::f_PureVirtualBase() 那么它可以工作,但显然有问题,因为叶子 对象中包含2 个Base )。
有什么提示吗?
更多信息以回答评论
我的目标架构比我在原始问题中提供的示例稍微复杂一些:
PureVirtualBase(SDK)
|
Base(SDK)
|
--SubClassA
--SubClassB(SDK)
--SubClassC(SDK)
--SubClassD(SDK)
LeafOne:继承自 SubClassA 和 SubClassB(SDK)
LeafTwo : 继承自 SubClassA 和 SubClassC(SDK)
LeafThree:继承自 SubClassA 和 SubClassD(SDK)
SubClassA 是我自己的私有代码。它提供自定义功能。SDK 方法应该能够将其视为 Base 实例。 此类不会被实例化,但它可以在执行某些处理时同时处理 LeafOne、LeafTwo 和 LeafThree。