指针地图与结构/容器地图(C++)

use*_*963 8 c++ dictionary pointers

我正在学习数据结构课,在教授的所有例子中,他总是使他的地图具有指向结构或容器的指针值,而不是保持结构或容器本身.

他只是把它作为一种习惯,还是有充分的理由来加速?

  • 我知道你可以使用数据指针来避免拥有冗余的数据副本,但仍然可以同时保存多个容器/结构中的数据.
  • 在这些例子中,情况并非如此.数据仅在该地图中.

jog*_*pan 10

在我看来,决定是否使用指针与对象有很多因素:

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应用程序的各种类型的窗口,按钮和菜单,您很可能希望使用指针并利用多态性.另一方面,如果您处理的是紧凑元素的大型结构,大小和形状都相同,并且您执行的操作涉及频繁迭代或批量复制,则直接存储对象是可以实现的.可能还存在这样的情况:如果不同时尝试并且基于存储器和时间基准的结果来决定则难以做出决定.


最后要注意的是,如果您最终使用指针,请考虑您正在构建的容器是否是在堆上分配的对象的最终所有者,或者只是维护临时指针.如果容器是这些对象的所有者,那么建议您使用智能指针而不是原始指针.