C++接口类导致函数调用(Qt)不明确
C++ interface class causes ambiguous function call (Qt)
这可能是因为我不完全理解C++中的接口是如何工作的,但现在我们开始:
我在QT5中有一个属性类的基本接口。
class IBaseProperty
{
public:
virtual ~IBaseProperty() {}
// Returns the property key as a string.
virtual QString getKey() = 0;
// Returns the property value as a raw string.
virtual QString getValueRaw() = 0;
// Sets the property key as a string.
virtual void setKey(QString key) = 0;
// Sets the property value as a raw string.
virtual void setValueRaw(QString value) = 0;
};
我还有一个模板化的接口扩展,可以更容易地对处理更特定数据类型的属性进行子类化。
template <class T>
class IProperty : public IBaseProperty
{
public:
virtual ~IProperty() {}
// Classifies a property with a Property_t identifier.
virtual Property_t getPropertyType() = 0;
// Returns the property value as the specified type.
// Bool is true if conversion was successful.
virtual T getValue(bool* success) = 0;
// Sets the property value as the specified type.
virtual void setValue(T value) = 0;
// Returns whether the current value can be converted correctly
// to the specified type.
virtual bool canConvert() = 0;
};
我的基本属性(仅实现IBaseProperty)如下所示:
class BaseProperty : public QObject, public IBaseProperty
{
Q_OBJECT
public:
explicit BaseProperty(QObject *parent = 0, QString key = "", QString value = "");
virtual QString getKey();
virtual QString getValueRaw();
public slots:
virtual void setKey(QString key);
virtual void setValueRaw(QString value);
protected:
QPair<QString, QString> m_Property; // KV pair this property holds.
};
我将其子类化为字符串属性-显然,基本属性只能返回字符串,但我希望在string/int/float/等之间保持相同的函数格式。属性中的getValue。在这种情况下,GetValue只是简单地调用getValueRaw来返回值。
class StringProperty : public BaseProperty, public IProperty<QString>
{
Q_OBJECT
public:
explicit StringProperty(QObject *parent = 0, QString key = "", QString value = "");
virtual inline Property_t getPropertyType() { return Prop_String; }
virtual QString getValue(bool* success);
virtual bool canConvert();
public slots:
virtual void setValue(QString value);
};
当我实现getValue和setValue:时,会出现歧义
inline QString StringProperty::getValue(bool* success)
{
*success = canConvert();
return getValueRaw(); // This line causes the ambiguity.
}
编译器抱怨:
C2385:"getValueRaw"的访问不明确:可能是"getValueRaw"在基"BaseProperty"中,或者可以是基中的"getValueRaw"IBaseProperty"。
我不完全确定在这种情况下该怎么办——我本以为IBaseProperty是一个纯虚拟类意味着函数无论如何都不能从这一点调用,所以只能从它实现的地方(BaseProperty)调用。解决这个问题的正确做法是什么?我不确定应该从哪个基类调用函数。
首先看来,这似乎是经典的钻石问题或钻石继承
String property
继承自BaseProperty
和IProperty
,并且它们都具有相同的基类IBaseProperty
。这就是为什么会有歧义。
问题是StringProperty
包含两个类型为IBaseProperty
的基类子对象。您可能只想要一个IBaseProperty
,在这种情况下,您需要使用虚拟继承。(将"接口"作为虚拟基类通常是个好主意。)
template <class T>
class IProperty : public virtual IBaseProperty
{ /*...*/ };
class BaseProperty : public virtual IBaseProperty, public QObject
{ Q_OBJECT; /*...*/ };
class StringProperty : public virtual IProperty<QString>, public BaseProperty
{ Q_OBJECT; /*...*/ };
推荐阅读:C++常见问题解答25.8至25.15。
- Visual C++(VS2017)中用户定义的转换不明确
- 重载类方法的不明确调用
- 为函数定义符号不明确的指针参数
- 父类的私有函数会导致对具有相同名称和相似参数的子类中的公共函数的不明确调用
- 在 C++17 中的命名空间和子命名空间中重载运算符是不明确的
- C++ 编译器错误:P1LinkedList.cpp:145:错误:重载的"to_string(int&)"调用不明确
- 对重载函数find_first_not_of的不明确调用
- 不明确的成员模板查找
- gcc出现不明确的模板实例化错误
- 调用'Node'构造函数是不明确的
- 如何解决不明确的运算符过载问题?
- 使用 nullptr 调用重载方法是不明确的
- 当我的阵列达到一定大小时,Qt 不起作用
- "fpclassify":对重载函数的不明确调用
- 对"列表"的引用不明确,包括头文件
- 删除全局隐式函数 - 避免使用不明确的运算符
- 当接收到不明确的规范时,表示图的邻接列表的数据结构
- Qt 中的错误不明确
- QT - QAction::eventFilter:不明确的快捷方式重载
- C++接口类导致函数调用(Qt)不明确