1

タイプ A のオブジェクトを生成するクラス (MyFactory) があります (myFactory はインスタンスになります)。ユーザーがクラス A を (たとえば、クラス B に) 拡張し、A の仮想メソッドをオーバーライドできるようにしたいと考えています。

たとえば、 A を拡張したくないユーザー:

A* myObject = myFactoryInstance.createObject();

そして、 A を B で拡張するユーザー向けの現在のトリック:

B* myObjectPrepare = new B()
myFactoryInstance.setNextObject( myObjectPrepare );
A* myObject = myFactoryInstance.createObject(); // Will look for a "next_object"
     /* Here, myObject (which is myObjectPrepare modified by createObject) 
        methods will dynamically link to B class methods. */

私の目標は、この操作を容易にすることです。

.

私は試した :

  template <class T>
  void MyFactory::set_requests_class() {
      new T(); 
      /* I don't want an instance, now. Just memorize class type
         at compilation time, and make instances of T along exec
      */
  }

(使い方: set_requests_class(); 問題: インスタンスを作りたくない)


それが解決策になる可能性があります:

myFactoryInstance.createObject<YourObjectTypeHere>();

しかし、テンプレート パラメータを必須にしたくありません (属性のデフォルト パラメータは c++11 以降でのみ可能です): A を拡張したくないユーザーのために、非常にシンプルに保ちたいです同じ理由で、「createObject」署名を変更します。

(私の将来のトリックは、B オブジェクトをインスタンス化し、それを属性として保持し、新しいインスタンス用に複製することです)

よろしくお願いします(どんな提案でも大歓迎です)

4

1 に答える 1

2

最も簡単な方法は、単にオーバーロードすることcreateObjectです。次の例を参照してください。

class A
{
public:
    A() { std::cout << "A"; }
};

class Subclass1 : public A
{
public:
    Subclass1() { std::cout << "Subclass1"; }
};

class AFactory
{
public:
    A* createInstance()
    {
        return new A();
    }
    template<typename Tsubclass>
    A* createInstance()
    {
        return new Tsubclass();
    }
};

int main()
{
    AFactory fact;
    A* pa = fact.createInstance();// creates A
    A* psubclass1 = fact.createInstance<Subclass1>();// creates Subclass1

    delete pa;
    delete psubclass1;
    return 0;
}

また、実際にオブジェクトを作成する前に作成するタイプを設定するデザインを保持する必要がある場合は、以下のようなセカンダリ ファクトリを使用してそれを行うことができます。ただし、あまりいいデザインではありません。基本的に、ファクトリ クラスは結果をキャストするラッパーとして機能するようになりました。外から見るともっと良いデザインがあるようです。

struct A
{
    A() { std::cout << "A"; }
};

struct Subclass1 : A
{
    Subclass1() { std::cout << "Subclass1"; }
};

struct GenericAFactoryBase
{
    virtual A* createInstance() = 0;
};

template<typename Tsubclass>
struct GenericAFactory : GenericAFactoryBase
{
    A* createInstance() { return new Tsubclass(); }
};

struct AFactory
{
    std::shared_ptr<GenericAFactoryBase> genericFactory;

    AFactory()
    {
        genericFactory.reset(new GenericAFactory<A>());
    }

    A* createInstance()
    {
        return genericFactory->createInstance();
    }
    template<typename Tsubclass>
    void SetType()
    {
        genericFactory.reset(new GenericAFactory<Tsubclass>());
    }
};

int main()
{
    AFactory fact;
    A* pa = fact.createInstance();// creates A

    fact.SetType<Subclass1>();
    A* psubclass1 = fact.createInstance();// creates Subclass1

    delete pa;
    delete psubclass1;
    return 0;
}
于 2012-09-22T22:17:33.790 に答える