简体   繁体   English

C ++中的容器:指针与引用

[英]Containers in C++: pointers vs references

I'm trying to understand the best practices for stl containers (specifically map) and wondering about the following: 我试图了解stl容器(特别是map)的最佳做法,并想知道以下几点:

map<string,blah> map1;
map<string,blah*> map2;

(1) blah a = = map2["a"]
a.foo = somethingelse;
map2["a"] = a;

(2) blah& a = map2.at("a")

(3) blah a = = map2.at("a")
a.foo = somethingelse;
map2["a"] = a;

(4) blah& a = map2["a"]
(5) blah& a = map2.at("a")

(6) blah* a = *map2.find("a")

(7) blah* a = map2["a"]

I understand that storing a reference over a pointer has the benefit of 1) not having to manage your own memory 2) behind able to access the objects from outside the map (their memory location doesn't change), while storing a pointer over a reference means that inserting elements into the map will be cheaper (copy the pointer, not the reference). 我知道在指针上存储引用的好处是1)不必管理自己的内存2)能够从地图外部访问对象(它们的存储位置不变)的背后,而在指针上存储指针reference意味着将元素插入到地图中会更便宜(复制指针,而不是引用)。

What about the other operations? 那其他操作呢? For example, find is logarithmic in size which suggest that it's better to use references because the memory will be contiguous. 例如,find的大小是对数的,这表明最好使用引用,因为内存将是连续的。

I'm assuming (1) and (3) are just bad ideas, but what about the others? 我假设(1)和(3)只是个坏主意,但是其他想法呢? Would it be correct to say that if my map is read-dominated I should use references, while if its write dominated (the objects are modified frequently), I should maybe use pointers? 正确地说,如果我的地图是读取主导的,我应该使用引用,而如果它的写入主导(对象经常被修改),我应该使用指针吗?

Now, lets' deal with this, statement after statement... 现在,让我们处理这个问题,一个接一个地陈述...

  1. I understand that storing a reference over a pointer has the benefit . 我知道在指针上存储引用有好处 Do you really store references? 您真的存储参考吗? see std::reference_wraper . 参见std::reference_wraper Do you know, underneath the hood, references are pointers, {just that on the front end, its a super strict type that binds once and on declaration} 您知道吗,在引擎盖下的引用是指针,{只是在前端,它是一种非常严格的类型,可在声明时绑定一次}

  2. not having to manage your own memory : No, so long it's an lvalue, memory must be managed. 不必管理自己的内存 :不,只要是左值,就必须对内存进行管理。 Either by you or the compiler (automatic storage duration) 由您或由编译器(自动存储持续时间)

  3. behind able to access the objects from outside the map ..., while storing a pointer over a reference ... will be cheaper (copy the pointer, not the reference). 能够从地图外部访问对象的背后...,同时将指针存储在引用上...会更便宜(复制指针,而不是引用)。 : std::map manages it's own memory, you only want to store pointer if it shouldn't manage the memory of the objects. std::map管理它自己的内存,如果它不管理对象的内存,则只想存储指针。 And Yes, it's cheaper to store pointers for non- integral types 是的,为非整数类型存储指针更便宜

  4. What about the other operations? 那其他操作呢? ... it's better to use references because the memory will be contiguous : Again, see point 1. Except if you meant values... Also, not all containers store their elements in a contiguous memory irrespective of what type they consume ...最好使用引用,因为内存将是连续的 :再次,请参见第1点。除非您是要使用值,否则...并非所有容器都将其元素存储在连续内存中,无论它们使用哪种类型

  5. Would it be correct to say that if my map is read-dominated I should use references, while if its write dominated (the objects are modified frequently), I should maybe use pointers? 正确地说,如果我的地图是读取主导的,我应该使用引用,而如果它的写入主导(对象经常被修改),我应该使用指针吗? : No! :不! See point 1 again... It doesn't really matter... just be const correct 再次看到第1点...没什么关系...只要保持正确

You maybe saw "T& at(key)" for your map, or perhaps something else that talked about references? 您可能在地图上看到“ T&at(key)”,或者其他谈论参考的内容? Containers do take values as references, but that's just for efficiency. 容器确实将值作为参考,但这只是为了提高效率。 They are then copied into the container. 然后将它们复制到容器中。

If you decide to put values into the container (option 1), then your item has to be copied when inserted, but then can be modified by reference: 如果您决定将值放入容器(选项1),则在插入项目时必须将其复制,但可以通过引用对其进行修改:

blah &a = map1["a"]
a.foo = somethingelse;
//  No need to do this: map1["a"] = a;

Or, shorter: 或者,更短:

map1["a"].foo = somethingelse;

When you do this with values, the map owns the object and will delete it when the map is deleted (among other times). 使用值执行此操作时,地图将拥有该对象,并且在删除地图时(以及其他时间),该对象将被删除。

If you store raw pointers, you must manage the memory. 如果存储原始指针,则必须管理内存。 I wouldn't advise that. 我不建议这样做。 I would instead consider putting shared_ptr or unique_ptr into your map. 相反,我会考虑将shared_ptr或unique_ptr放入您的地图中。 You do that if you need to have the value outside of the map stay alive even if the map is destroyed. 如果您需要使地图之外的值保持活动状态,即使该地图已被破坏,也可以这样做。

map<string,shared_ptr<blah>> map3;
shared_ptr<blah> myPtr = make_shared<blah>();
map3["a"] = myPtr;

Here, I can still use myPtr even after the map goes away. 在这里,即使地图消失了,我仍然可以使用myPtr。 After everything pointing to the object is gone, the object will be deleted. 指向该对象的所有内容消失后,该对象将被删除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM