C++中使用自定义类型作为std::map值的问题求助
嘿,我来帮你搞清楚这个问题~ 你遇到的报错完全是因为std::map的[]运算符的特性导致的,先给你拆解清楚:
为什么会报错?
你用myMap[intVal]的时候,这个操作背后的逻辑是:如果intVal这个key在map里不存在,它会自动默认构造一个Type对象插入到map中,然后返回这个对象的引用。但你的Type类只定义了带3个int参数的构造函数,没有提供无参数的默认构造函数,所以编译器找不到Type::Type(),就抛出了那个错误。
而你之前的insert操作是完全没问题的:make_pair(keyVal, Type(intVal,intVal,intVal))是直接构造了一个Type对象,然后插入到map里,这部分不需要用new(你要存储对象而非指针的思路是对的,完全没必要用指针,反而容易带来内存管理问题)。
几个解决方法,你可以选适合自己的:
1. 给Type添加默认构造函数
最简单的方式是给你的Type类加一个默认构造函数,或者给现有构造函数的参数加上默认值(这样相当于同时支持默认构造和带参构造):
class Type { public: // 带默认参数的构造函数,既可以用3个int初始化,也可以无参数默认构造 Type(int a = 0, int b = 0, int c = 0) { // 这里写你的初始化逻辑,比如给成员变量赋值 } void useMemberFunction() { // 你的成员函数逻辑 } };
这样myMap[intVal]在key不存在时就能正常构造对象了。
2. 避免使用[]运算符,改用find()访问元素
如果你不想给Type加默认构造函数(比如业务逻辑不允许默认构造的对象存在),那可以用find()来查找已存在的元素,这个操作不会触发默认构造:
// 查找key对应的迭代器 auto it = myMap.find(intVal); if (it != myMap.end()) { // 找到元素了,调用成员函数 it->second.useMemberFunction(); } else { // 处理key不存在的情况,比如提示错误,或者手动插入对象 // 比如用insert或者emplace插入: myMap.insert(make_pair(intVal, Type(intVal, intVal, intVal))); // 或者更高效的emplace: // myMap.emplace(intVal, intVal, intVal, intVal); }
这个方法的好处是不会意外创建你不需要的默认构造对象,更符合业务逻辑。
3. 用emplace()高效插入元素(C++11及以上)
如果你用的是C++11或更高版本,推荐用emplace()来代替insert,它可以直接在map内部构造Type对象,避免了临时对象的拷贝,更高效:
// 直接在map里构造Type对象,参数就是Type构造函数的参数 myMap.emplace(keyVal, intVal, intVal, intVal);
访问的时候还是用上面的find()方法,避免触发默认构造。
总结
你完全可以用map<int, Type>来存储自定义类型的实例,不需要用指针(也不建议随便用new,容易造成内存泄漏)。报错的核心是[]运算符的自动默认构造特性,解决要么给Type加默认构造,要么换用find()来访问元素。
内容的提问来源于stack exchange,提问作者Gotsiller

