複数の継承オブジェクトをクローンする方法は?
-
08-10-2019 - |
質問
クローン可能なインターフェイスを定義しました。
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
解決
あなたを持っている clone
関数返品a Cloneable *
正しい。
インターフェイスの1つが派生した場合、曖昧な変換が得られます Cloneable
.
編集: ALFはコメントで、それが可能であるだけではないと指摘しています Leaf::clone
返すには Leaf*
, 、実際にはそうすることが望ましいです。私は修正されました。
他のヒント
あなたはおそらくそれについて言及しなかったでしょう Interface
または、他のいくつかの基本クラスも継承します Cloneable
. 。 「あいまいな変換」は意味します Leaf
おそらく複数が含まれています Cloneable
基本クラスのサブオブジェクト。 (コバリアントリターンタイプの問題は、同じ問題の直接的な結果である可能性があります。)
この問題を使用して解決する必要があります 仮想継承 (推奨およびリンクされた読み取り:C ++ FAQ Liteトピック25.8から25.13)。まず、変更してください すべて のインスタンス : public Cloneable
に : public virtual Cloneable
.
私はあなたがおそらく事実上継承していないと言うことができ、言うことができます 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
ベースオブジェクト。