2
#include <memory>

class Base
{
    std::shared_ptr<Base> create() const; // Returns a default constructed object
}

どの程度まで派生したすべてのメンバーBaseがコピー構築可能であり、デフォルト構築可能であるとします。が欲しい

std::shared_ptr<Base> create() const;

適切な動的タイプのオブジェクトを作成するメソッドですが、ボイラープレート コードは使用したくありません。

作ることは可能ですか

std::shared_ptr<Base> create() const;

静的にバインドされていますが、内部で何らかの形で正しい型を見つけ、デフォルトのコンストラクターを使用してオブジェクトを作成しますか? おそらくC++ 11を使用しています。

4

2 に答える 2

1

理想的には、静的関数とおそらく非静的create()関数があります。これを実現する賢い方法があります。

  1. クラスを定義しSuperBaseます。仮想デストラクタと純粋仮想create()関数が必要です。通常の遅延バインディング OOP の動作には、このクラスへのポインター/参照を使用します。

  2. Baseから継承するクラス テンプレートを定義しSuperBaseます。Baseのテンプレート パラメータは、Derivedクラスの型になります。Baseには、 という静的関数を持つ traits クラス テンプレートもありますcreate()。この静的create()関数は、 でデフォルト オブジェクトを作成しますnew。トレイトのcreate()関数を使用すると、 a と純粋仮想関数のBase両方が定義されます。static_create()SuperBase::create()

  3. Derivedから継承して実装しBase<Derived>ます。

これが完了したら、派生型を使用していることがわかっている場合はDerived::create()、新しい型を静的に作成するように記述できます。そうでない場合は、いつでもインスタンスのcreate()メソッドを使用できます。SuperBaseポリモーフィズムは、必要な/必要なポリモーフィック インターフェイスを備えているため、壊れていません。これは、関数と関数Base<D>を自動定義するヘルパー クラスであるため、通常は直接使用しません。static_create()create()Base<D>

サンプル コードを以下に示します。

#include <memory>
#include <iostream>

class SuperBase
{
  public:
    virtual ~SuperBase() = default;
    virtual std::shared_ptr<SuperBase> create() const = 0;
};

template <typename T>
struct Base_Traits
{
  static T* create()
  {
    return new T;
  }
};

template <typename Derived, typename Traits=Base_Traits<Derived>>
class Base : public SuperBase
{
  public:   
    // Define a static factory function...
    static std::shared_ptr<SuperBase> static_create()
    {
      return std::shared_ptr<SuperBase>{Traits::create()};
    }

    // Define pure virtual implementation...
    std::shared_ptr<SuperBase> create() const override
    {
      return static_create();
    }
};

class Derived : public Base<Derived>
{
};

int main()
{
  auto newone = Derived::static_create();  // Type known @ compile time
  auto anotherone = newone->create();      // Late binding; type not known @ compile time
}
于 2012-07-20T19:40:22.973 に答える
1

create()インスタンスがまだないため、関数はおそらく静的である必要があります。しかし、パラメータがなければ、あなたが望むことはできません... もちろん、テンプレートを使用しない限り:

class Base
{
public:
    template<typename T>
    static std::shared_ptr<Base> create() const
    {
        return std::shared<Base>(new T);
    }
};

次に、次のように使用します。

std::shared_ptr<Base> ptr(Base::create<Foo>());

または、必要に応じて:

std::shared_ptr<Base> ptr(Foo::create<Foo>());
于 2012-07-20T19:04:57.480 に答える