为什么不通过将指针移到vector[0]来实现c++std::vector::pop_front()呢

why not implement c++ std::vector::pop_front() by shifting the pointer to vector[0]?

本文关键字:vector c++std 实现 pop front 指针 为什么不      更新时间:2023-10-16

为什么不能通过简单地将矢量名称中包含的指针移动一点来为C++矢量实现pop_front()?因此,在包含数组foo的向量中,foo是指向foo[0]的指针,因此pop_front()将使指针成为foo = foo[1],而括号运算符将只进行正常的指针数学运算。这与C++如何跟踪您在为数组分配空间时使用的内存有关吗?

我承认,这与我看到的关于为什么std::vector没有pop_front()函数的其他问题类似,但我没有人问你为什么不能移动指针。

如果vector这样做,它将无法释放内存。

通常,您希望每个vector对象的开销较小。这意味着您只存储三项:指向第一个元素的指针、容量和长度。

为了实现您的建议,每个vector所有)都需要一个额外的成员变量:从第零个元素所在的开始指针的偏移量。否则,内存将无法释放,因为它的原始句柄将丢失。

这是一种权衡,但通常情况下,可能具有数百万个实例的对象的内存消耗比对vector执行这是性能上最糟糕的事情的极端情况更有价值。

因为实现者希望优化向量的大小。它们通常使用3个指针,一个用于开头,一个表示容量(分配的末尾),一个代表末尾。

执行所需操作会向每个向量再添加4个字节(在c++程序中有很多这样的字节),但收效甚微:向量的契约是在推送新元素时快速,删除和插入是"未知"操作,它们的性能比类的大小更重要。

我开始输入一个详细的答案,解释如何分配和释放内存,但在输入完所有答案后,我意识到仅靠内存问题并不能证明为什么pop_front没有像这里的其他答案所建议的那样存在。

在大多数情况下,在额外成本是另一个指针的向量中具有pop_front是合理的。在我看来,问题在于push_front。如果容器具有pop_front,那么它也应该具有push_front,否则容器不一致。push_front对于矢量容器来说肯定是昂贵的(除非您将pushes与pops相匹配,这不是一个好的设计)。没有push_front,如果在没有push_front功能的情况下执行大量pop_front操作,则向量实际上是浪费内存。

现在,pop_frontpush_front需要一个类似于向量(恒定时间随机访问)的容器,这就是为什么存在deque的原因。

您可以,但这会使实现稍微复杂一些,并添加一个指向类型大小的开销指针(这样它就可以跟踪实际分配的地址)。这值得吗?有时首先考虑其他可以更好地处理您的使用的结构(可能是deque?)。

可以做到这一点,但vector被设计成一个简单的容器,具有恒定的时间索引查找和从末尾推送/弹出功能。按照您的建议执行会使实现复杂化,因为它必须跟踪分配的起点和"当前"起点。更不用说,你仍然不能保证在前面持续插入时间,但有时你可能会得到它。

如果你需要一个前后插入和取出时间恒定的容器,这正是deque的用途,不需要修改vector来处理它。

您可以使用std::deque而不是std::vector。这是一个双端队列,也有类似向量的访问成员。它同时实现前推和后推/弹出。

http://www.cplusplus.com/reference/stl/deque/

您的建议的另一个缺点是,您将浪费内存空间,因为在移位后无法使用数组左侧的内存空间。执行pop_front()的次数越多,在向量被破坏之前浪费的时间就越多。