假设我有以下课程:
class MyOtherClass{
std::unordered_map<int, std::multimap<int, MyClass*>> _xy;
void putObject(int x,int y,MyClass* obj);
void containsXkey(int x){
bool found = false;
std::unordered_map<int,std::multi map<int,MyClass*>>::const_iterator index = _xy.find(x);
if(index = _xy.end(){
found = false;
}else{
found = true;
}
return found;
}
}
说我想编写一个函数来将MyClass放在坐标(2,3)处,然后我会做这样的事情:
void putObject(int x, int y, MyClass* obj){
if(!containsXKey(x){
//Since it doesn't contain an empty multimap, I'm creating one.
std::multimap<int, MyClass*> foo; //This is created on the stack
_xy[x] = foo; //What happens here ?
}
std::multimap<int,MyClass*>& foo = _xy[x];
foo.insert(y,obj);
}
所以我的问题是:最初unordered_map
中没有条目,所以我第一次想要在特定键上添加项目时,我需要创建一个multimap
。在堆栈上创建multimap
。那么当我将它分配给密钥时会发生什么?是复制品吗?它存放在哪里?
答案 0 :(得分:10)
与所有动态大小的容器一样,映射容器将其元素保留在动态内存存储*(“堆”**)上。
对象本身可能位于堆栈,堆栈等,但在对象内部可能存在指向动态内存的子对象或指针。
那么当我将它分配给密钥时会发生什么?
地图将确保内部缓冲区可以容纳另一个键值对,否则,它将展开以支持另外一个元素的存储。
是否正在制作副本?
取决于键/值如何传递给地图。如果键/值支持移动语义并且键作为r值引用传递,则不会复制,而是移动。但如果该类不支持移动语义或者该键作为const引用传递,则它将被复制。
它存储在哪里?
该标准没有规定如何在内部实施地图,因此每个图书馆都可以按照自己喜欢的方式实施。 Microsoft std::unordered_map
将键值对保留在链表中,其他库可以选择将地图元素保存在矢量中。
std::multimap<int, MyClass*> foo; //This is created on the stack
_xy[x] = foo; //What happens here ?
在这种情况下,在堆栈上创建foo
。运算符[]
本身在堆上创建默认创建的std::multimap
,然后运算符=
将foo
的内容(非{}}复制到_xy[y]
。
*假设映射使用标准分配器,可以设置从其他存储分配内存的特定分配器。
**标准没有直接声明“stack”和“heap”之类的字,但是声明了以下术语:自动存储(“堆栈”),动态存储(“堆”),静态存储(“数据段“)和线程存储(”TLS“)。