我已经定义了一个Cloneable接口:
struct Cloneable
{
virtual Cloneable * clone(void) const = 0;
}
我还有一些其他接口类(与问题无关的内容):
struct Interface
{
};
struct Useful_Goodies
{
};
我创建了一个继承自上述类的叶子对象:
struct Leaf : public Cloneable, public Interface, public Useful_Goodies
{
Leaf * clone(void) const // Line #1 for discussion.
{
return new Leaf(*this);
}
};
我收到了错误:
overriding virtual function return type differs and is not covariant from 'Cloneable::clone'
如果我将类型更改为Cloneable *
,则会收到以下错误消息:
'return' : ambiguous conversions from 'Leaf *' to 'Cloneable *'
我的问题(全部相关):
Cloneable
的要求
接口我正在使用这个范例作为通用编程(记录,字段和数据库)的一部分。
编译器:MS Visual Studio 2008;平台:Windows XP& Vista的
答案 0 :(得分:2)
让clone
函数返回Cloneable *
是正确的。
如果您的某个界面也来自Cloneable
,您将获得不明确的转化。
修改:Alf在评论中指出Leaf::clone
不仅可以返回Leaf*
,实际上它更适合这样做。我有所纠正。
答案 1 :(得分:1)
您可能没有提到Interface
或其他一些基类也继承Cloneable
。 “模糊转换”意味着Leaf
可能包含多个Cloneable
基类子对象。 (协变返回类型的问题可能是同一问题的直接结果。)
您需要使用virtual inheritance解决此问题(推荐和链接阅读:C ++ FAQ Lite主题25.8到25.13)。首先,将: public Cloneable
的所有实例更改为: public virtual Cloneable
。
答案 2 :(得分:1)
我可以冒险说你可能从多个路径中实际上从Cloneable
继承。也就是说,直接Cloneable
之外的其他一些基础(直接或间接)从Cloneable
继承。这使得从Leaf*
到Cloneable*
的转换不明确,因为Cloneable
中有多个Leaf
基数。
简单的解决方案是使用界面中的虚拟继承:
struct Cloneable {
virtual Cloneable * clone() = 0;
};
struct Interface : virtual Cloneable {
};
struct Test : virtual Cloneable, Interface {
virtual Test* clone() {
return new Test(*this);
}
};
虚拟继承意味着即使Interface
和Test
都继承自Cloneable
,也只有一个Cloneable
基础对象。