web-dev-qa-db-ja.com

C ++でのポリモーフィックオブジェクトのコピー

_Derived1_、_Derived2_、および_Derived3_から派生した基本クラスBaseがあります。

_Base* a_として保存する派生クラスの1つのインスタンスを作成しました。ここで、_Base* b_として保存するオブジェクトのディープコピーを作成する必要があります。

私の知る限り、クラスをコピーする通常の方法は、コピーコンストラクターを使用し、_operator=_をオーバーロードすることです。ただし、aの型が_Derived1_、_Derived2_、または_Derived3_のいずれであるかわからないため、コピーコンストラクターまたは_operator=_。この作業をきれいに行うために私が考えることができる唯一の方法は、次のようなものを実装することです。

_class Base
{
public:
  virtual Base* Clone() = 0;

};
_

そして、次のように派生クラスにCloneを実装します。

_class Derivedn : public Base
{
public:
  Base* Clone() 
  {
    Derived1* ret = new Derived1;
    copy all the data members
  }
};
_

JavaはCloneをかなり使用する傾向がありますが、これを行うC++の方法は他にもありますか?

37
doron

これは、ポリモーフィッククラスに対してC++で行う方法ですが、オブジェクトのコピーコンストラクター(暗黙的またはプライベートの可能性があります)を作成する場合は、メンバーの明示的なコピーを行う必要はありません。

class Base
{
public:
  virtual Base* Clone() = 0;
};

class Derivedn : public Base
{
public:
  //This is OK, its called covariant return type.
  Derivedn* Clone() 
  {
    return new Derivedn(*this);
  }
private:
  Derivedn(const Derivedn) : ... {}
};
36
template <class T>
Base* Clone (T derivedobj) {
  T* derivedptr = new T(derivedobj);
  Base* baseptr = dynamic_cast<Base*>(derivedptr);
  if(baseptr != NULL) {
    return baseptr;
  }
  // this will be reached if T is not derived from Base
  delete derivedptr;
  throw std::string("Invalid type given to Clone");
}

この関数が派生クラスに必要とする唯一のことは、それらのコピーコンストラクターがパブリックにアクセス可能であることです。

2
Jon Garbe