質問

ここにあります Clone() 私のクラスの実装:

    MyClass^ Clone(){
        return gcnew MyClass(this->member1, this->member2);
    }

現在、から派生したクラスが約 10 個あります MyClass. 。実装はどの場合でも同じです。電話する必要があるという事実のせいで gcnew それぞれの場合に実際のクラス名を使用して、ほぼ同一の実装を 10 個作成する必要があります。 Clone().

1つだけ書く方法はありますか Clone() 10 個の派生クラスすべてに対応する基本クラスのメソッドは?

編集: クラスのオブジェクトの 1 つを介してクラスのコンストラクターを呼び出す方法はありますか?実際の派生クラスのコンストラクターを呼び出す方法で。何かのようなもの:

MyClass ^obj2 = obj1->Class->Construct(arg1, arg2);

私はこれを C++/CLI で行っていますが、他の言語からの回答も歓迎します。

役に立ちましたか?

解決

、昔ながらのC ++では、コンパイル時のポリモーフィズム(不思議-繰り返しテンプレートパターン)でこれを行うことができます。あなたの派生クラスでコピー可能ですと仮定すると、あなただけ書くことができます:


class Base
{
public:
    virtual Base* Clone() const = 0;
//etc.
};
template <typename Derived>
class BaseHelper: public Base
{
    //other base code here

    //This is a covariant return type, allowed in standard C++
    Derived * Clone() const
    {
         return new Derived(static_cast<Derived *>(*this));
    }
};

そして、同じように使用


class MyClass: public BaseHelper<MyClass>
{
    //MyClass automatically gets a Clone method with the right signature
};

あなたは再びクラスから派生し、それがシームレスに動作していないことに注意してください - 。中間クラスをテンプレート化することによって、あなたがオプション「のデザインは、」再び導出するために持っているか、もう一度再書き込みCloneを開始

他のヒント

ない私の知るという++ Cインチあなたが言うように、あなたはクローン()の各実装で異なるクラスのオブジェクトを作成する必要があります。

フム、私はあなたがここにFactoryパターンを使用することができると思います。すなわち:ます。

MyClass Clone(){
    return MyClassFactory.createInstance(this.getClass(), this.member1, this.member2, ...);
}

工場では、渡されたクラスタイプに基づいてサブクラスのインスタンスを作成する必要があります。だから、おそらくそれはあなたのアプローチと同じ欠点を持っています。

代わりにコピー コンストラクターを使用することをお勧めします (派生クラスは基本実装のコピー コンストラクターを呼び出すこともできるため)。C++ プログラマーにとって馴染みのある領域なので、これも便利です。

このインスタンスでは、リフレクションを使用してコピー コンストラクター自体を呼び出す単一の Clone メソッドを作成できる場合があります。

Jeffrey Richter が『フレームワーク設計ガイドライン』の本の中で次のように述べていることもおそらく注目に値します。「ICloneable インターフェイスは、明示的に文書化されていない契約を伴う非常に単純な抽象化の一例です。一部の型はこのインターフェイスを実装しています Clone メソッドを使用してオブジェクトの浅いコピーを実行しますが、一部の実装では深いコピーが実行されます。なぜなら、このインターフェースは何なのか Clone を実装する型のオブジェクトを使用する場合、メソッドが行うべきことは完全に文書化されていませんでした。 ICloneable, 、何が得られるかわかりません。 これによりインターフェースが役に立たなくなります" (私の言葉を強調)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top