在C ++中进行基本向量实现时,我在push_front
问题中遇到问题(下面)_Alloc
是分配器类,content_
是指向数据的指针,{ {1}}和size_
就是他们所说的,capacity_
是一个检查指针是否为空的函数。 (empty()
类型为pointer
)
测试:
value_type *
输出:
25
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
vector<int> v;
for (int i = 1; i <= 25; ++i)
{
v.push_front(i);
}
for (auto &a : v)
{
std::cout << a << "\n";
}
问题是什么(使用我的代码)?
答案 0 :(得分:3)
首先,您的代码非常混乱,因为您使用的是两个
复制循环中的变量。因为pos
总是索引一个
在迭代器i
后面,你在复制之前破坏了值
它一个。如果类型有一个小问题,这将工作
析构函数,但一般不会工作。做循环
没错,你必须在两个目标时都使用赋值
和源是构造元素和副本
否则构造函数。
但最大的问题是你在复制错误 方向。您需要从最高到最低复制 重叠复制工作。
编辑:
粗略地说:最简单的实现将包含三个
指针:begin
,end
和top
,对应于开头
的数据,初始化数据的结束和顶部的
可用(已分配)内存。把一切都改回来
一个元素(假设不为空):
std::uninitialized_copy( end - 1, end, end );
++ end;
std::copy_backward( begin, end - 2, end - 1 );
(请注意,这是通用的。将1
更改为您拥有的许多内容
向后移动,并begin
到插入点,你就是
得到了通用插件。另一方面,它不使用
分配器的construct
功能;为此,你必须这样做
实现您自己的uninitialized_copy
版本。)
另请注意,在新元素之后,end
已更改
构造,但在copy_backward
之前。为了推理
背后这个:想想如果建设会发生什么
新元素抛出异常。或者,如果其中一个分配
抛出一个例外。然后你试图破坏对象。
如果过早增加end
,则会尝试破坏
没有完全建造的物体;迟到了,你不会
破坏所有已完全构造的对象。
如果你想写出副本(出于教学原因):
_Alloc().construct( end, *(end - 1) );
++ end;
for ( auto current = end - 2; current != begin; -- current ) {
*(current + 1) = (current);
}
重要的是1)构造成新分配的
元素,但在移动一个元素时分配(copy
)
另一个已构建的元素,2)确定你
永远不要将值移动到本身不存在的元素中
感动了。第二点意味着当你向下移动时
从较低的地址开始(对应于
被删除的元素,因此可以被覆盖),以及何时被删除
向上移动,你从更高的元素(最高的元素)开始
这将被移动到新的记忆中,因此复制构造)。
答案 1 :(得分:2)
在for循环中复制值(for (iterator i = begin(); i != end(); ++i, ++pos)
),从头开始,将第一个元素移动到第二个元素,然后将同一个元素从第二个位置移到第三个位置,等等。
另请注意,在将每个元素复制到下一个插槽之前销毁每个元素会导致未定义的行为。