vector :: erase如何从它的内​​部数组中删除所选元素

时间:2015-01-25 22:35:54

标签: c++ arrays vector

由于vector类型的对象在内部由数组支持,因此vector类的erase函数如何从它的内​​部数组中删除所选元素?

我正在寻找至少一个基本代码示例的深入解释。

3 个答案:

答案 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;

    }
};