如何在类初始化时将类插入stl映射

How to insert class into stl map on class initialization

本文关键字:插入 stl 映射 初始化      更新时间:2023-10-16

已解决:http://pastebin.com/seEaALZh

我试图创建一个简单的项目系统,在那里我可以通过它的id来获取项目信息。我不能使用数组,因为项目id是随机的。我想使用声明的项作为变量,并且我想通过其id快速找到任何项信息。我找到的唯一方法是stl映射。

所以我有一个简单的代码:

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

由于某种原因,程序崩溃了。如何在类初始化时正确地将类数据插入映射?

问题在于初始化顺序。brass_knucklesgolf_club的静态构造函数在Stuff的静态构造函数之前首先运行,因此它们试图插入尚未构造的映射中。

此外,您永远不希望在头文件中包含变量DEFINITION,因为如果在多个源文件中包含头文件,则最终会有多个定义,这最多会导致链接失败。因此,您应该将DEFINITION从.h文件移到.cpp文件中。将它们放在Stuff的定义之后将解决初始化顺序问题。

如果您想在其他编译单元中使用变量,可以在头文件中声明变量:

extern const c_items brass_knuckles, golf_club;

你不能把c_item放在那样的Stuff中而是

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

但你也需要@Chris Dodd 提出的所有建议

所以

c_items::c_items(int id, char name[], int type) : id(id), type(type), name(name)
{}
extern const c_items  brass_knuckles,      golf_club;

以及在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....};