Yiin
Yiin

Reputation: 659

How to insert class into stl map on class initialization

SOLVED: http://pastebin.com/seEaALZh

I was trying to create simple items system, where i can get item information by its id. I cant use array, because items ids are lets say random. I want to use declared items as variables and i want to quickly find any item info by its id. The only way i found is stl map.

So I have this simple code:

  1. main.h

    #include <iostream>
    #include <map>
    
    enum
    {
        weapon,
        ammo
    };
    
    class c_items
    {
        bool operator()(const c_items& l, const c_items& r) const
        {
            return (l.id < r.id);
        }
    public:
        c_items(void){};
        c_items(int id, char name[], int type);
        char *name;
        int type;
        int id;
    };
    
    extern std::map<int,c_items> Stuff;
    
    c_items::c_items(int id, char name[], int type) : id(id), type(type), name(name)
    {
        Stuff[id] = c_items(id, name, type);
    }
    
    const c_items
        brass_knuckles          (546, "Brass knuckles", weapon),
        golf_club               (2165, "Gold club", weapon);
    
  2. main.cpp

    #include "main.h"
    
    std::map<int,c_items> Stuff;
    
    using namespace std;
    
    int main()
    {
        // cout << Stuff[2165].name.data();
        return 1;
    }
    

And for some reason program crashes. How to correctly insert class data into map on class initialization?

Upvotes: 0

Views: 299

Answers (2)

alexbuisson
alexbuisson

Reputation: 8469

you cannot put c_item in Stuff like that instead

 std::map<int,c_items> Stuff = { {item1.id, item1}, {item2.id, item2}};

but you also need to all the recommendation made by @Chris Dodd

so

c_items::c_items(int id, char name[], int type) : id(id), type(type), name(name)
{}

extern const c_items  brass_knuckles,      golf_club;

and in the main.cpp

 const c_items  brass_knuckles = {546, "Brass knuckles", weapon);
    const c_items golf_club = (2165, "Gold club", weapon);
    std::map<int,c_items> Stuff = { {brass_knuckles.id, brass_knuckles}, etc....};

Upvotes: 1

Chris Dodd
Chris Dodd

Reputation: 126193

The problem is order of initialization. The static constructors for brass_knuckles and golf_club run first, before the static constructor for Stuff, so they attempt to insert into a map that is not yet constructed.

In addition, you NEVER want variable DEFINITIONS in a header file, since if you include the header file in multiple source files, you end up with multiple definitions, which will at best cause a link failure. So you should move the DEFINITIONS out of the .h file and into the .cpp file. Putting them AFTER the definition of Stuff will fix the order of initialization problem.

You can have a DECLARATION of the variables in the header file if you want to use them in other compilation units:

extern const c_items brass_knuckles, golf_club;

Upvotes: 1

Related Questions