web-dev-qa-db-ja.com

C ++クラスをマップコンテナに挿入する

C++のマップがあり、クラスを値として入力し、文字列をキーとして入力したいと思います。しようとすると、エラーが発生します'Scene_Branding' : illegal use of this type as an expressionこの型を式として違法に使用しているのですが、その理由がわからないようです。ここにいくつかのコードがあります。

 string CurrentScene = "Scene_Branding";
 map<string, Scene> Scenes;
 Scenes.insert(std::make_pair("Scene_Branding", Scene_Branding));  //<-- Illegal Error parameter 2

これがシーンブランディングヘッダーです。

#ifndef Scene_Branding_H
#define Scene_Branding_H

#include "Scene.h"
#include <iostream>
#include <string>


class Scene_Branding : Scene
{
public:
 Scene_Branding();
 ~Scene_Branding();
 void Draw();
};

#endif

これがシーンヘッダーです。

#ifndef Scene_H
#define Scene_H

#include <iostream>
#include <string>

class Scene
{
public:
 Scene();
 ~Scene();
 virtual void Draw();

};

#endif

そしてここにcppファイルがあります。

シーンcpp。

#include "Scene.h"

Scene::Scene()
{

}
Scene::~Scene()
{

}
void Scene::Draw(){
 std::cout << "Hey";
}

Scene_Branding cpp

#include "Scene_Branding.h"

Scene_Branding::Scene_Branding()
{

}

Scene_Branding::~Scene_Branding()
{

}

void Scene_Branding::Draw()
{
 std::cout << "Drawing from Scene_branding";
}
15
Fouf

まず、オブジェクト自体をマップに格納するのではなく、オブジェクトへのポインタを格納します。

次に、クラス自体ではなく、Scene_Brandingのインスタンスをstd :: make_pairに指定する必要があります。

編集:ポインタを保存する方法は次のとおりです。

 string CurrentScene = "Scene_Branding";
 map<string, Scene*> Scenes;
 Scenes.insert(std::make_pair("Scene_Branding", new Scene_Branding()));

しかし、あなたはこの種の質問をしたので、ポインターのような概念をさらに理解するために、良いc ++の本を読むことをお勧めします。

24
erelender

試してください:

Scenes.insert(std::make_pair("Scene_Branding", Scene_Branding()));
7

私はあなたがそれをしたくないと思います。

  1. c ++には実行時型マッピングはなく、型ではなくオブジェクトを格納します。
  2. ポリモーフィック型をSTLコンテナに格納することはできません。必要に応じて、代わりにboost::ptr_mapを使用してください。

したがって、「新しい」コード:

class Scene
{
public:
  virtual ~Scene();                  // Virtual Destructor, it's a base class
  virtual Scene* clone() const = 0;  // Polymorphic construction
private:
  // whatever you wish
};

class Scene_Branding: public Scene
{
public:
  virtual Scene_Branding* clone() const { return new Scene_Branding(); }
};

そしてそれらを保存する新しい方法:

const std::string SceneBrandingKey = "Scene_Branding";

typedef boost::ptr_map<std::string, Scene> scenes_type;

scenes_type Scenes;
Scenes.insert(SceneBrandingKey, new Scene_Branding());

そして、あなたはそれをこうして使うことができます:

Scenes["Scene_Branding"].process(); // Note: use '.' not '->'

Boost Pointer Container の良いところは、例外安全性などを除いて、ポリモーフィックタイプ向けでありながら、STLの動作/インターフェイスを模倣しているため、迷子にならないことです:)

3
Matthieu M.

ジェネリックマップコンテナを使用する場合は、クラスにポインタが必要です。それ以外の場合、クラスの新しいオブジェクトが空になる可能性があります...ポインタを使用すると機能します。

std::map<std::string, Type*> map_;

インサート

map_["key"] = *Type;

注:コンパイラへの-fpermisiveフラグが設定されていない場合は、パスが必要です。* map_コンテナに挿入するときにconstではありません。

宜しくお願いします、

ハビエル、