1

次のコードは、1 行目で「'Cloneable*' から 'AClass*' に変換できません」というコンパイル エラーを出しています。これに関する具体的な理由。親切に助けてください。

struct Cloneable
{
 virtual Cloneable* clone()
  {
  cout << "Cloneable";
  return new Cloneable;
  }

  virtual ~Cloneable() {}
};


struct AClass : public Cloneable
{
  virtual AClass* clone()
  {
  cout << "AClass";
  return new AClass;
  }
};

int main()
{ 
 Cloneable* s1 = new AClass;
 AClass* s2 = s1->clone();      //Line 1
return 0;
}
4

3 に答える 3

1

あなたはポインターを呼び出しclone()ています。Cloneableこのメソッドは を返すCloneable*ので、これが必要です:

Cloneable* s2 = s1->clone();

これにより、 がインスタンス化されますAClass。これは、この複製イディオムを使用する標準的な方法です。ポリモーフィズムを正しく使用している場合、Cloneable*またはを持っているかどうかは問題ではありませんAClass*。したがって、通常Cloneable*AClass::clone()あまりにも戻ってきます。もちろん、できればスマート ポインターを返します。

struct AClass
{
  virtual std::unique_ptr<Cloneable> clone();
};

struct AClass : public Cloneable
{
  virtual std::unique_ptr<Cloneable> clone();
};
于 2013-02-27T19:27:34.187 に答える
1

キャストで「機能」させることは可能ですが、あなたがしていることは非常に危険です。動的に割り当てられた 2 つのオブジェクトを削除するのを忘れました。このように「動的メモリ割り当てを非表示にする」こともあまりお勧めできません。特に、どこにも削除しないでください。std::unique_ptr または std::shared_ptr を使用するか、単にオブジェクトをスタックに割り当てる方がはるかに簡単です。

編集:最初に率直な答えを出さなかったことに対する私の謝罪:

AClass* s2 = dynamic_cast<AClass*>(s1->clone()); 
于 2013-02-27T19:22:33.683 に答える
1

基本的に、新しい AClass* を基本クラス ポインターに格納すると、clone を呼び出した結果が Cloneable* になり、これを AClass* にダウンキャストする必要がありますが、これは常に安全であるとは限りません。したがって、コンパイラはdynamic_cast ()

于 2013-02-27T19:15:26.420 に答える