クローン方式
タイプをクエリし、その情報から構築できる言語によって提供されるものはありませんが、さまざまな方法でクラス階層に機能を提供できます。最も簡単な方法は、仮想メソッドを使用することです。
struct Base {
virtual ~Base();
virtual std::auto_ptr<Base> clone(/*desired parameters, if any*/) const = 0;
};
これは少し異なることをします:現在のオブジェクトのクローンを作成します。これは多くの場合必要なものであり、オブジェクトをテンプレートとして保持し、必要に応じて複製および変更することができます。
Tronicを拡張すると、クローン関数を生成することもできます。
なぜauto_ptr?したがって、 newを使用してオブジェクトを割り当て、所有権の譲渡を明示的にすることができます。呼び出し元は、 deleteによってオブジェクトの割り当てを解除する必要があることは間違いありません。例えば:
Base& obj = *ptr_to_some_derived;
{ // since you can get a raw pointer, you have not committed to anything
// except that you might have to type ".release()"
Base* must_free_me = obj.clone().release();
delete must_free_me;
}
{ // smart pointer types can automatically work with auto_ptr
// (of course not all do, you can still use release() for them)
boost::shared_ptr<Base> p1 (obj.clone());
auto_ptr<Base> p2 (obj.clone());
other_smart_ptr<Base> p3 (obj.clone().release());
}
{ // automatically clean up temporary clones
// not needed often, but impossible without returning a smart pointer
obj.clone()->do_something();
}
オブジェクトファクトリ
要求どおりに実行し、インスタンスとは独立して使用できるファクトリを取得したい場合は、次のようにします。
struct Factory {}; // give this type an ability to make your objects
struct Base {
virtual ~Base();
virtual Factory get_factory() const = 0; // implement in each derived class
// to return a factory that can make the derived class
// you may want to use a return type of std::auto_ptr<Factory> too, and
// then use Factory as a base class
};
get_factoryは同じ役割の半分を果たし、戻り型(およびその意味)が唯一の違いであるため、クローンメソッドの場合と同じロジックと機能の多くを使用できます。
工場についてもすでに数 回取り上げました。SimpleFactoryクラスを適応させて、ファクトリオブジェクト(get_factoryによって返される)がグローバルファクトリへの参照と、作成に渡すパラメータ(たとえば、クラスの登録名-boost ::functionとboost::bindを適用する方法を検討する)を保持するようにすることができます。これを使いやすくします)。