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

时间:2016-02-21 22:40:42

标签: c++ pointers dictionary stl containers

我正在尝试了解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"]

据我所知,在指针上存储引用的好处是:1)无需管理自己的内存2)能够从地图外部访问对象(它们的内存位置不会改变),同时存储一个引用上的指针意味着将元素插入到地图中会更便宜(复制指针,而不是引用)。

其他操作怎么样?例如,find的大小是对数的,这表明使用引用会更好,因为内存将是连续的。

我假设(1)和(3)只是坏主意,但其他人呢?如果说我的地图是读取主导的,我应该使用引用,如果它的写入占主导地位(对象经常被修改),我应该使用指针吗?

2 个答案:

答案 0 :(得分:2)

现在,让我们“处理这个,声明后的声明......

  1. 我知道在指针上存储引用有好处。你真的存储参考文献吗?见std::reference_wraper。你知道,在引擎盖下,引用是指针,{只是在前端,它是一个超级严格的类型绑定一次和声明}

  2. 无需管理自己的内存:不,只要它是左值,就必须管理内存。由您或编译器(自动存储持续时间)

  3. 能够从地图外部访问对象...,同时将指针存储在引用上...会更便宜(复制指针,而不是引用)。var bks: Book[] = [ new Book(1, "vamsee") ]; 管理它自己的内存,如果它不应该管理对象的内存,你只想存储指针。是的,存储非integral types

  4. 指针的成本更低
  5. 其他操作怎么样? ...最好使用引用,因为内存将是连续的:再次,请参阅第1点。除非您的意思是值...此外,并非所有容器都将其元素存储在连续的内存中,而不管它们的类型是什么消耗

  6. 如果说我的地图是读取主导的,我应该使用引用,如果它的写入占主导地位(对象经常被修改),我应该使用指针吗?:不!再看第1点......这并不重要......只需const correct

答案 1 :(得分:0)

您可能会在地图中看到“T&amp; at(key)”,或者其他可能涉及引用的内容?容器确实将值作为参考,但这只是为了提高效率。然后将它们复制到容器中。

如果您决定将值放入容器(选项1),那么您的项目必须在插入时复制,但随后可以通过引用进行修改:

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

或者,更短:

map1["a"].foo = somethingelse;

使用值执行此操作时,地图拥有该对象,并在删除地图时删除它(以及其他时间)。

如果存储原始指针,则必须管理内存。我不建议这样做。我会考虑将shared_ptr或unique_ptr放入您的地图中。如果你需要让地图之外的值保持活着,即使地图被破坏,你也可以这样做。

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

在这里,即使地图消失,我仍然可以使用myPtr。指向对象的所有内容都消失后,该对象将被删除。