如何克隆多重继承对象?

发布于 2024-09-28 03:46:17 字数 976 浏览 12 评论 0原文

我定义了一个 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 和 Windows XP远景

I have defined a Cloneable interface:

struct Cloneable
{
  virtual Cloneable * clone(void) const = 0;
}

I have also some other interface classes (content not relevant to issue):

struct Interface
{
};

struct Useful_Goodies
{
};

I have created a leaf object which inherits from the above classes:

struct Leaf : public Cloneable, public Interface, public Useful_Goodies
{
  Leaf * clone(void) const  // Line #1 for discussion.
  {
     return new Leaf(*this);
  }
};

I'm getting the error:

overriding virtual function return type differs and is not covariant from 'Cloneable::clone'

If I change the type to Cloneable *, I get this error message:

'return' : ambiguous conversions from 'Leaf *' to 'Cloneable *'

My Questions (all related):

  1. How can the leaf class resolve the
    requirements of the Cloneable
    interface?
  2. Is there a better solution to implement a
    Cloning contract, where all objects
    are guaranteed to implement cloning?

I'm using this paradigm as part of generic programming (records, fields & database).

Compiler: MS Visual Studio 2008; Platforms: Windows XP & Vista

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

宣告ˉ结束 2024-10-05 03:46:17

让您的 clone 函数返回 Cloneable * 是正确的。

如果您的接口之一也派生自 Cloneable,您将得到不明确的转换。

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

Having your clone function return a Cloneable * is correct.

You will get an ambiguous conversion if one of your interfaces also derives from Cloneable.

Edit: Alf points out in the comments that not only is it possible for Leaf::clone to return a Leaf*, it's actually preferable for it to do so. I stand corrected.

峩卟喜欢 2024-10-05 03:46:17

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

您需要使用 虚拟继承(推荐和链接阅读:C++ FAQ Lite 主题 25.8 到 25.13)。首先,将 : public Cloneable所有实例更改为 : public virtual Cloneable

You probably failed to mention that Interface or some other base class also inherits Cloneable. The "ambiguous conversion" means Leaf probably contains multiple Cloneable base class subobjects. (A problem with covariant return type could be a direct result of the same problem.)

You'll want to solve this problem using virtual inheritance (recommended and linked reading: C++ FAQ Lite topics 25.8 through 25.13). To start with, change all instances of : public Cloneable to : public virtual Cloneable.

夜还是长夜 2024-10-05 03:46:17

我可以冒险说,您可能实际上没有从多个路径继承 Cloneable 。也就是说,除了直接的 Cloneable 之外,您的一些其他基础(直接或间接)继承自 Cloneable。这使得从 Leaf*Cloneable* 的转换变得不明确,因为 Leaf 中有多个 Cloneable 基数。

简单的解决方案是使用接口的虚拟继承:

struct Cloneable {
   virtual Cloneable * clone() = 0;
};
struct Interface : virtual Cloneable {
};
struct Test : virtual Cloneable, Interface {
   virtual Test* clone() {
      return new Test(*this);
   }
};

虚拟继承意味着即使 InterfaceTest 都继承自 Cloneable,也只有一个单个Cloneable基础对象。

I can risk and say that you are probably non virtually inheriting from Cloneable from more than one path. That is, some of your other base besides the direct Cloneable inherits (directly or indirectly) from Cloneable. This makes the conversion from Leaf* to Cloneable* ambiguous as there are more than one Cloneable base in your Leaf.

The simple solution is using virtual inheritance from the interface:

struct Cloneable {
   virtual Cloneable * clone() = 0;
};
struct Interface : virtual Cloneable {
};
struct Test : virtual Cloneable, Interface {
   virtual Test* clone() {
      return new Test(*this);
   }
};

Virtual inheritance means that even if both Interface and Test inherit from Cloneable, there is only a single Cloneable base object.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文