1

我定义了一个 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 *'

我的问题(所有相关):

  1. 叶类如何解决Cloneable 接口的需求?
  2. 是否有更好的解决方案来实现克隆合约,保证所有对象都实现克隆?

我将这种范式用作通用编程(记录、字段和数据库)的一部分。

编译器:MS Visual Studio 2008;平台:Windows XP 和 Vista

4

3 回答 3

2

让你的clone函数返回 aCloneable *是正确的。

如果您的接口之一也派生自Cloneable.

编辑: Alf 在评论中指出,不仅可以Leaf::clone返回 a Leaf*,而且这样做实际上更可取。我站得更正了。

于 2010-10-15T16:23:06.990 回答
1

您可能没有提到Interface或者其他一些基类也继承了Cloneable. “模糊转换”意味着Leaf可能包含多个Cloneable基类子对象。(协变返回类型的问题可能是同一问题的直接结果。)

您将希望使用虚拟继承来解决这个问题(推荐和链接阅读:C++ FAQ Lite 主题 25.8 到 25.13)。首先,将的所有实例更改: public Cloneable: public virtual Cloneable

于 2010-10-15T17:28:31.160 回答
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继承TestCloneable,也只有一个Cloneable基础对象。

于 2010-10-15T17:28:32.813 回答