c – 当`key / value`被插入`std :: map`时,它是否自己创建了对象的副本?

前端之家收集整理的这篇文章主要介绍了c – 当`key / value`被插入`std :: map`时,它是否自己创建了对象的副本?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
这是受到有效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.

猜你在找的C&C++相关文章