为什么不能通过简单地将向量名称中包含的指针移到一个点来为C ++向量实现pop_front()
?因此,在包含数组foo
的向量中,foo
是指向foo[0]
的指针,因此pop_front()
会使指针foo = foo[1]
和括号运算符只做正常的指针数学。这是否与C ++如何跟踪您为数组分配空间时所使用的内存有关?
这与我已经看到的std::vector
没有pop_front()
功能的其他问题类似,我承认,但我还没有人问过为什么你不能移动指针。
答案 0 :(得分:2)
因为实施者想要优化矢量的大小。它们通常使用3个指针,一个用于开头,一个用于容量(分配的结束),一个用于结束。
执行您需要的操作会为每个向量添加另外4个字节(并且在c ++程序中有很多这样的字节)几乎没有什么好处:向后移动的合同要快速推回新元素,删除和插入是“不正常”的操作和他们的表现只比班级规模小。
答案 1 :(得分:2)
如果vector
执行此操作,vector
将无法释放内存。
通常,您希望每个vector
对象的开销很小。这意味着您只存储三个项目:指向第一个元素的指针,容量和长度。
为了实现您的建议,每个vector
永远(所有)都需要一个额外的成员变量:第0个元素所在的起始指针的偏移量。否则,内存无法释放,因为它的原始句柄将丢失。
这是一种权衡,但一般来说,一个可能拥有数百万个实例的对象的内存消耗比做绝对最糟糕的事情的情况更有价值,你可以在性能方面做到 { {1}}。
答案 2 :(得分:2)
我开始输入一个精心解答的答案,解释内存是如何分配和释放的,但在输入内容之后,我意识到单独的内存问题并不能证明为什么pop_front
不存在,因为这里提出的其他答案。
在向量中使用pop_front
,其中额外成本是另一个指针在大多数情况下是合理的。在我看来,问题是push_front
。如果容器有pop_front
,那么它也应该有push_front
,否则容器不一致。 push_front
对于矢量容器来说绝对是昂贵的(除非您将push
es与您的pop
匹配,这不是一个好设计。没有push_front
,如果有很多pop_front
次操作没有push_front
功能,那么向量确实会浪费内存。
现在需要pop_front
和push_front
的容器类似于向量(常量随机访问),这就是deque
的原因。
答案 3 :(得分:1)
你可以,但它会使实现稍微复杂化,并在类型的大小上添加一个开销指针(因此它可以跟踪实际的分配地址)。这值得吗?有时。首先考虑可以更好地处理您的使用的其他结构(可能是deque?)。
答案 4 :(得分:1)
你可以这样做,但vector
被设计成一个简单的容器,具有恒定的时间索引查找和从最后的推/弹。做你的建议会使实现复杂化,因为它必须跟踪分配的开始和“当前”开始。更不用说你仍然不能保证在前面插入恒定的时间,但有时你可能会得到它。
如果您需要一个具有恒定时间前后插入和移除的容器,这正是deque
的用途,则无需修改vector
来处理它。
答案 5 :(得分:1)
您可以使用std::deque
代替std::vector
。它是一个双端队列,也有类似矢量的访问成员。它实现了前后推/弹。
答案 6 :(得分:0)
你的建议的另一个缺点是你会浪费内存空间,因为你不能在转移后使用阵列左侧的内存空间。执行pop_front()
的次数越多,在向量被破坏之前就会浪费的越多。