由于vector类型的对象在内部由数组支持,因此vector类的erase函数如何从它的内部数组中删除所选元素?
我正在寻找至少一个基本代码示例的深入解释。
答案 0 :(得分:5)
通过复制擦除元素后的元素,然后填充"空"元素在最后。然后将尺寸标记为少一个。
大致代码就像这样[ACTUAL实现将使用技巧来避免制作不必要的副本等,例如使用移动语义]
template<typename T>std::vector::erase(int index)
{
// Call destructor of T for the one being deleted.
storage[index].T~();
for(i = index; i < size-1; i++)
{
storage[i] = storage[i+1];
}
storage[size-1] = T();
size--;
}
如果你想看看REAL实现是如何工作的,我建议你启动调试器,然后自己尝试一下。但如果它非常复杂且难以理解,请不要感到惊讶 - 编写图书馆代码的人通常非常精通语言的工作方式,并会使用&#34;书中的任何技巧&#34; 34;使它更快/更小/更整洁。
答案 1 :(得分:2)
当删除除末尾之外的任何元素时,删除之后的元素将被移除。
答案 2 :(得分:2)
向量必须分配内存而不调用任何构造函数。然后它可以使用展示位置和展示位置删除(也称为手动调用析构函数)。
Placement new 涉及指定内存地址,并调用带有this
指向该内存地址的构造函数。 Placement delete 涉及运行析构函数,但不释放内存。 (向量将保持在内存块上,然后将另一个对象放置到同一位置。)
该向量还可以使用复制赋值运算符,复制构造函数,移动构造函数,移动赋值运算符做好自己的工作。
在C ++ 11之前,向量要求元素是CopyAssignable,所以基本的向量实现(显然我省略了很多函数):
template<typename T>
struct vector
{
T *base;
size_t m_count;
size_t m_capacity;
// start off with space reserved for 20 elements, but no actual elements
vector(): base((T *)new unsigned char[20 * sizeof(T)]),
m_count(0), m_capacity(20) {}
void push_back(T const &t) {
if ( m_count == m_capacity )
reserve(m_capacity * 2);
// placement new, using copy-constructor
new(base + m_count) T(t);
++m_count;
}
void erase(size_t index)
{
// Use the assignment-operator to shuffle all objects down by one
// (The "being erased" object doesn't get destructed directly, but it
// loses its state by having another object assigned to it. This is
// permitted because T must be CopyAssignable prior to C++11. In
// C++11 this function would try to Move objects down instead.
for (size_t i = index; i < m_count - 1; ++i)
base[i] = base[i+1];
// Call destructor for the last object (which we currently have 2 of)
base[m_count-1].~T();
--m_count;
}
};