C++ 指针映射与结构/容器映射(C+;+;)

C++ 指针映射与结构/容器映射(C+;+;),c++,dictionary,pointers,C++,Dictionary,Pointers,我在上一节数据结构课,在教授的所有例子中,他总是让他的地图有一个指向结构或容器的指针值,而不是保持结构或容器本身 他这样做只是一种习惯,还是有一个很好的理由,比如提高速度 我知道,您可以使用指向数据的指针,以避免数据的冗余副本,但仍然可以同时在多个容器/结构中包含指向该数据的方向 在这些例子中,情况并非如此。数据只在那张地图上 一种可能是内容类型不可复制。将对象实例直接存储在容器中的好处是,可以避免一定程度的间接寻址&节省指针本身使用的空间。通过直接存储对象实例而不是存储指针,您可以在时间和空

我在上一节数据结构课,在教授的所有例子中,他总是让他的地图有一个指向结构或容器的指针值,而不是保持结构或容器本身

他这样做只是一种习惯,还是有一个很好的理由,比如提高速度

  • 我知道,您可以使用指向数据的指针,以避免数据的冗余副本,但仍然可以同时在多个容器/结构中包含指向该数据的方向
  • 在这些例子中,情况并非如此。数据只在那张地图上

一种可能是内容类型不可复制。

将对象实例直接存储在容器中的好处是,可以避免一定程度的间接寻址&节省指针本身使用的空间。通过直接存储对象实例而不是存储指针,您可以在时间和空间效率方面获得成功。如果您对处理器缓存的工作原理有一点了解,就不难看出在容器中“内联”存储对象实例如何具有真正的性能优势


在不对包含的类型或容器使用模式进行任何假设的情况下,默认容器应该是
std::vector
(而不是
std::vector
)。从这个默认选择开始,如果您可以看到使用模式将如何从其他类型结构的性能概要中受益,那么您将使用向量以外的东西。同样,如果指针间接寻址是必需的,或者从性能角度看是值得的,那么您将拥有指向对象的容器存储指针。如果包含的类型不可复制构造,则需要间接寻址;如果容器不“拥有”其对象,则也需要间接寻址。

在我看来,决定是否使用指针或对象涉及到许多因素:

1。您是否需要多态性?

如果您希望维护基类对象的容器,但随后在其中存储各种派生类的对象,则必须使用指针,因为否则虚拟函数调用将无法正确解析

2。存储对象的大小及其对复制操作的适用性

指针比对象更受欢迎的一个关键原因是,在容器上执行的各种操作都涉及到复制存储在容器中的对象。许多存储操作(例如
std::vector::push_back()
std::map::insert()
),一些检索操作(例如
std::vector::operator[]
,然后将对象存储在局部变量中),以及容器“内部”执行的一些操作都是如此,例如,当向量增长超过其容量时,重新分配向量,或重新灰化
std::unordered_map
。请注意,复制操作可能不太重要,这取决于您如何选择容器以及如何使用它(例如,使用
std::vector::reserve()
分配足够的空间,使用
std::vector::emplace_back()
进行存储,并且从不对检索到的元素进行本地复制可能意味着永远不会进行复制)

但是,如果您希望生成大量副本(或者如果分析现有代码发现生成了许多副本),那么使用指针而不是对象显然会有所帮助,因为指针很小,并且在内存中对齐良好。同样,如果存储的对象实际上比指针小,那么这也没有多大意义

3。对容器及其内容物执行的其他操作

即使您正在处理的对象比指针大,并且您需要大量的复制操作,使用指针也不一定是首选。考虑一种情况,您存储大量的中等大小对象(例如,每个字节16个),并且经常需要遍历整个容器并执行某种统计计算。当您将这些对象直接存储在向量中时,您可以在迭代过程中获得很高的缓存效率:当您检索一个对象时,将从内存中检索整个缓存线,从而使接下来几个对象的检索速度更快。当使用指针时,通常情况并非如此;相反,在检索元素后,必须取消对指针的引用,从而导致从可能未缓存的内存区域执行另一个移动操作

显然,这一切都取决于存储对象的类型和大小,以及执行操作的类型和频率。如果您正在处理的对象是GUI应用程序的各种类型的窗口、按钮和菜单,那么您很可能希望使用指针并利用多态性。另一方面,如果您处理的是大小和形状完全相同的紧凑元素的巨大结构,并且您执行的操作涉及频繁的迭代或批量复制,那么直接存储对象是不可靠的。在某些情况下,如果不同时尝试这两种方法并根据记忆和时间基准的结果做出决定,就很难做出决定



作为最后一点,如果最终使用指针,请考虑您正在构建的容器是否是堆上的对象的最终所有者,或者只是维护临时指针。如果容器是这些对象的所有者,您最好使用智能指针,而不是原始指针。

为什么不问问教授?这不是一个StupID问题。我可以告诉你,实际上我的工作是超过15年的专业C++开发和100万个写在作业上的代码,我很少把一个结构或类放在一个容器里面。99%以上的时间我使用某种类型的指针(最近它很可能是智能指针)。虽然我已经回答了,但我不会