这是受到有效C#第一版中的Item的启发,警告天真地覆盖GetHashCode().
对不起,我没有支持代码.顺便说一句,这不是一个功课,我只是不熟悉C / STL,也无法找到有关实施的信息.
假设我创建了自己的名为person的类,它有3个公共可变字符串字段:
>名字,
>初中
>姓氏
它还提供了一个小于运算符来比较一个人与另一个人的名字,首先是名字,然后是中间名,然后是姓氏 – 就是全部.
我创建了一个从人到int(比如年龄)的地图,并用大约20个键/值对填充它.我还存储指向数组中键的指针.然后我更改了第五个指针指向的对象的第一个名称,并尝试使用此修改的键查找相应的年龄(请记住该对象是可变的并且是大开的).
为什么会这样?
A)因为std :: map使用的密钥没有改变(被复制),我改变了自己的副本,现在找不到我的密钥.但这怎么可能呢?我没有提供自己的复制构造函数.也许默认的一个是由编译器创建的?
B)std :: map集合实际上是一个红黑树,我碰巧有一个指向键的直接指针.当我更改了密钥后,我直接在树的节点中更改了密钥.现在很可能我的节点没有正确定位,并且使用正确的树搜索算法无法找到它.我应该删除该节点,然后修改它们的密钥,然后再次重新插入它.如果是这种情况,那么我怀疑STL集合通常是相当危险的,并且会导致新手出错.
C)还有别的吗?
我很感激你的见解.
解决方法
使用std容器时,所有数据都将复制到容器中.对于地图,这没有什么不同.
映射放置在数据上的一个限制是密钥是不可变的.插入后,它将被修复以更改您必须找到/擦除的密钥并重新插入以更改密钥的值.
struct Person { std::string first; std::string middle; std::string last; Person(std::string const& f,std::string const& s,std::string const& l) { BLABLA } bool operator<(Person const& rhs) { return BLABLABLA;} }; std::map<Person,int> ageMap; ageMap[Person("Tom","Jones","Smith")] = 68; ageMap[Person("Tom","I","Smith")] = 46; ageMap[Person("Tom","II","Smith")] = 24;
当您创建Person数组时,除非数组包含const指针,否则它将失败.
Person* pMap[3]; pMap[0] = &ageMap.begin().first; // Fail need a const pointer. Person const* pMapConst[3]; pMapConst[0] = &ageMap.begin().first; // OK. Note a const pointer.