C ++ Вставка класса в контейнер карты - PullRequest
13 голосов
/ 17 февраля 2010

У меня есть карта на 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

и вот заголовок Scene Branding ..

#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";
}

Ответы [ 4 ]

22 голосов
/ 17 февраля 2010

Во-первых, не храните сами объекты на карте, сохраняйте указатели на ваши объекты.

Во-вторых, вам нужно передать экземпляр Scene_Branding в std :: make_pair, а не в сам класс.

EDIT: Вот как вы храните указатели:

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

Но, поскольку вы задали этот тип вопросов, я рекомендую вам прочитать хорошую книгу по c ++ для дальнейшего понимания таких понятий, как указатели.

7 голосов
/ 17 февраля 2010

Попробуйте:

Scenes.insert(std::make_pair("Scene_Branding", Scene_Branding()));
3 голосов
/ 17 февраля 2010

Я думаю, вы не хотите этого делать.

  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, так что вы не потерялись:)

0 голосов

Вам нужны указатели в классе, если вы используете универсальные контейнеры карт, в результате возможен новый объект, пустой вашего класса ... с указателями работает!

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

Вставить

map_["key"] = *Type;

ПРИМЕЧАНИЕ: если флаг -fpermisive для компилятора не установлен, вам нужно передать * Введите not const при вставке в контейнер map_.

С наилучшими пожеланиями,

Хавьер,

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...