1

仮想関数を持つ基本クラスから継承する派生クラスがあります。オブジェクトをベクトルに追加したいので、オブジェクトを作成するためにスマートポインター(shared_ptr)を使用しています。しかし、特定のタスクを実行するためにオブジェクトを処理するコードが繰り返されることに気付いたので、テンプレートがコードを改善するためのソリューションになると考えました。これはこれまでの私の試みです(正確なコードではなく、簡略化されています):

class Base{

    public:
     virtual ~Base(){}
     virtual void display_message() = 0;
};

class DerivedA : public Base{
    DerivedA(){}
};

class DerivedB : public Base{
    DerivedB(){}
};



//THE template- 
//<hold the smart pointer that points to different derived objects>

template<typename T1>

class HandleInstances{
      private:            

         vector<T1> ObjectVector;
         //the iterator

         T1 sp_base;

      public:

        HandleInstance(const T1 & sp){
            sp_base = sp; // set smart pointer
        }
        //somefunctions

        //this is what i need to figure out
        void AddToVector(){
             ObjectVector.push_back(sp_base(new 'The derived class') );
        }



};

AddToVector 関数がここでの問題です。オブジェクトの要素を追加するには、この push_back( "the smart pointer"( new "the class" )); を実行する必要があります。テンプレートに (オブジェクトではなく) クラスを受け入れさせ、それを push_back() の関数に実装するにはどうすればよいですか?

4

3 に答える 3

1

オブジェクトをクラスとして使用しようとしていますが、それは機能しません (オブジェクトoperator()に正しいオブジェクトを返す が含まれている場合を除きますが、余談になります)。

代わりに試してください:

void AddToVector(){
    ObjectVector.push_back(T1(sp_base));
}

これにより、新しいオブジェクトが作成され、新しいオブジェクトのコピー コンストラクターが呼び出されて渡さsp_baseれます。したがって、本質的にのコピーを作成しますsp_base

于 2012-08-16T21:15:34.323 に答える
0

これは挑戦的なものです - なぜですか?テンプレートは、テンプレート パラメータに基づいてクラスのバリアントを動的に構築することにより、C++ の一種の前処理ステップとして動作するためです。

言い換えると、shared_ptr<DerivedA>shared_ptr<DerivedB>互いにまったく関係がありません。C++ では、テンプレートは基本的に 2 つの別個のクラス宣言 (無関係な型) のように作成されるためです。

それらに含まれるポインターは両方とも基本クラスの子孫ですが、shared_ptrs 自体は aVector<Bool>および aである可能性がありFooます。単一の基本クラスから継承することは問題ではありませんが、テンプレートによって生成されたクラスはそうではありませDerivedAん。DerivedB

そうは言っても、ある程度の柔軟性があります。クラスのインターフェースにファクトリ関数を配置すると、次のようになります。

class DerivedA : public Base{
    public:
    static shared_ptr<DerivedA> construct{
        return shared_ptr<DerivedA>(new DerivedA());
    };
};

....similar for DerivedB

次に、次のようなことができます。

template<typename T>
class HandleInstances{
  private:            

     vector<shared_ptr<T> > ObjectVector;

  public:

    //this is what i need to figure out
    void AddToVector(){
         ObjectVector.push_back(T::construct());
    }
};

そして、あなたは大丈夫なはずです。あなたがしていることは、後でオブジェクトを作成するためにクラス自体を保存できないという事実を補うために、各クラスに機能を与えることです。知らせ:

  1. HandleInstances のテンプレート パラメーターは、shared_ptr 型ではなく基本型です。
  2. ConstructDerivedA と DerivedB で異なる型を返しています。
  3. Baseこれらの関数はconstruct互換性のある型を返さないため、Base から継承されません。
  4. ObjectVector でタイプを混在させたり一致させたりすることはまだできません。(ボーナス: より多くの型を使用して型をラップし、これを処理する場合は可能です: boost::anyを参照してください
于 2012-08-16T22:19:58.653 に答える
0

関数もテンプレートにします。

template<typename T2>
void AddToVector(){
    ObjectVector.push_back(smart(new T2));
}

push_backメンバー変数よりもスマートポインターを使用するつもりだったと思いますsp_base

于 2012-08-16T21:15:14.353 に答える