我有三个类这样的结构:
#include <iostream>
using namespace std;
class Keyword
{
public:
virtual float GetValue() = 0;
};
class CharacterKeyword : public Keyword
{
public:
virtual float GetValue(){return _value;}
private:
float _value;
};
class MeasurementKeyword : public Keyword
{
public:
virtual float GetValue(){return _value;}
private:
float _value;
};
class AddressType : public CharacterKeyword, public MeasurementKeyword
{
private:
float address;
float addresExt;
};
int main()
{
AddressType *a = new AddressType();
a->GetValue();
return 0;
}
我得到以下内容:
In function ‘int main()’:
error: request for member ‘GetValue’ is ambiguous
error: candidates are: virtual float Keyword::GetValue()
error: virtual float MeasurementKeyword::GetValue()
error: virtual float CharacterKeyword::GetValue()
我已经对多重继承做了一些阅读,我知道它有很多陷阱 - 这就是其中之一。我需要我的类结构是这样的,所以我想知道是否有一种方法可以使用模板来解决这个问题?
更新
阅读完您的评论之后,我原先的想法是,我可以通过模板化{{AddressType
来CharacterKeyword
AddressType
和MeasurementKeyword
之间的AddressType
。 1}}。并在更新的代码中使用它。 OR 我可以指定我想要的成员的命名空间。由于模板化的方式尚未被提及作为答案,这是一个糟糕的解决方案吗?我应该只指定我想要的成员的名称空间吗?
template <class T>
class AddressType : public T
{
private:
float address;
float addresExt;
};
int main()
{
AddressType<MeasurementKeyword> *a = new AddressType<MeasurementKeyword>();
a->GetValue();
return 0;
}
答案 0 :(得分:15)
这是因为diamond inheritance pattern,要解决错误,您可以指定您希望该成员的特定命名空间。
paddressType->MeasurementKeyword::GetValue()
或
paddressType->CharacterKeyword::GetValue()
AddressType
类可以从它继承的两个类中访问GetValue
个成员,但不能选择一个(调用不明确)。 ::
)有助于指定您真正想要的那一个。 答案 1 :(得分:5)
像这样定义AddressType:
class AddressType : public CharacterKeyword, public MeasurementKeyword
{
public:
using MeasurementKeyword::GetValue;
private:
float address;
float addresExt;
};
答案 2 :(得分:3)
通常,当您遇到deadly diamond of death时,表明您应该重新考虑您的设计。但是,如果您无法避免这种情况,C ++会以virtual inheritance的形式提供解决方案。虚拟继承解决了一些“钻石含糊不清”,但它也很笨重。例如,您必须在派生类的构造函数中显式调用父类的非默认构造函数。
再次,最好的方法是首先避免使用钻石。我用C ++编程已经很多年了,到目前为止,我的代码中从来没有遇到过这个问题。