2

C++ では、型 (クラスなど) をパラメーターとして関数に渡す方法はありますか?

これが必要な理由の説明: 抽象dataクラスとクラスがありmanagerます。クラスには、のmanager派生クラスのオブジェクトのリスト (この場合はマップ) が含まれていますdataこの質問unique_ptrの回答で述べたように、私はこれを使用します。

class Data{}; // abstract

class Manager
{
    map<string, unique_ptr<Data>> List;
};

dataここで、マネージャーに新しいストレージを追加したいとします。

class Position : public Data
{
    int X;
    int Y;
}

そのタイプのオブジェクトを作成してそれを参照するようにマネージャに指示するにはどうすればよいunique_ptrでしょうか?

Manager manager;
manager.Add("position data", Position);

この場合、最初にインスタンスを作成してからマネージャーに送信する必要がないため、クラスをマネージャー クラスPositionの関数に渡す必要があります。add

そして、どうすればそのクラスのオブジェクトをに追加できますListか?

C++でそれを行う方法があるかどうかはわかりません。それが簡単にできない場合は、回避策を本当に知りたいです。どうもありがとう!

4

4 に答える 4

5

テンプレートを使用できます。派生する各タイプDataでは、次のプロトタイプを持つ「作成者」関数を定義する必要がありますDerived* create()。内部で呼び出されます ( を返すこともできますがunique_ptr、より多くのメモリが必要になります)。

元:

struct Position: public Data
{
    // ...
    static Position* create()
    {
        return new Position();
    }
};

Addメソッドは次のようになります。

template<typename D>
void Add(String str)
{
    List.insert(std::make_pair(str, std::unique_ptr<Data>(D::create())));
}

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

Manager manager;
manager.Add<Position>("position data");

編集

このメソッドcreateを使用して、関数を削除することもできます。Add

template<typename D>
void Add(String str)
{
    List.insert(std::make_pair(str, std::unique_ptr<Data>(new D())));
}

利点: データ構造コードのコードが少ない。

不便: データ構造は、構築方法をあまり制御できません。

于 2012-10-28T14:08:07.213 に答える
3

このようなものはどうですか:

class Manager
{
 public:
  template <typename T>
  void addData(const std::string& title)
  {
    List.insert(std::make_pair(title, std::unique_ptr<Data>(new T));
  }
 private:   
  map<string, unique_ptr<Data>> List;
};

それから

Manager manager;
manager.addData<Position>("position data");
于 2012-10-28T14:08:45.463 に答える
1

使用unique_ptrとは、動的に割り当てられたオブジェクトの操作にコミットすることを意味します。(正確ではありません: を呼び出さないカスタムのデリータを指定することもできますがdelete、それは型の一部になります。これは、動的に割り当てられていないオブジェクトの操作をコミットすることになることを意味します。)

void Manager::Add(String title, unique_ptr<Data> d) {
    List[title] = d;
}

次のように呼び出します。

Manager manager;
unique_ptr<Data> pos(new Position);
// Set it up
manager.Add("position data", pos);

注:データ オブジェクトで何かを実行できるようにしたい場合は、おそらく 内で少なくとも 1 つの仮想関数を宣言する必要がありますclass Data

于 2012-10-28T14:09:18.727 に答える
0

関数を次のように定義します。

void Manager::Add(String title,Position pos){ /*snip*/ }

次に、次のように関数を使用できます。

Manager manager;
Position posData;
//setup the posData
manager.Add("position data",posData);
于 2012-10-28T13:59:52.670 に答える