学习C++ 语言的矢量清除与擦除

189 阅读2分钟

C++向量有许多成员函数。其中两个是clear()和erase()。clear()"删除 "向量的所有元素。erase() "删除 "单个元素或元素的范围。矢量的erase()成员函数有两个重载的变体。

本文的标题实际上是 "向量clear()成员函数与向量erase()成员函数,在C++中"。这是对这两个成员函数的比较。它涉及到何时使用哪个,如何使用哪个,以及在哪些条件下使用哪个。

为了在C++程序中使用一个向量,程序应该以下列方式开始。

#include <vector>

#include <iostream>

using namespace std;

文章内容

Vector clear()

clear()成员函数 "删除 "了向量的所有元素。它的语法是

void clear()

它返回无效。下面的程序说明了它的使用,表达式为:"vtr.clear();"。

#include <vector>

#include <iostream>

using namespace std;

 

int main()

{

    vector<char> vtr = {'P', 'Q', 'R', 'S', 'T', 'U'};

 

    for (vector<char>::iterator it = vtr.begin(); it != vtr.end(); it++)

        cout << *it << ' ';

    cout << endl;

 

    vtr.clear();

 

    for (vector<char>::iterator it = vtr.begin(); it != vtr.end(); it++)

        cout << *it << ' ';

    cout << endl;

 

    return 0;

}

输出就是这一行。

P Q R S T U

如果矢量没有被清除,输出将是两行相同的序列。没有显示第二行,因为所有的元素都被清除了。

const向量和clear()

当一个向量声明前面有const时,意味着向量的元素不能被删除或改变。如果一个表达式试图改变或删除任何元素,程序将无法编译。测试一下下面的程序,注意它是不能编译的。

#include <vector>

#include <iostream>

using namespace std;

 

int main()

{

    const vector<char> vtr = {'P', 'Q', 'R', 'S', 'T', 'U'};

 

    for (vector<char>::const_iterator it = vtr.begin(); it != vtr.end(); it++)

        cout << *it << ' ';

    cout << endl;

 

    vtr.clear();

 

    for (vector<char>::const_iterator it = vtr.begin(); it != vtr.end(); it++)

        cout << *it << ' ';

    cout << endl;

 

    return 0;

}

如果该程序被测试,将发出一个错误信息,并且不会有任何编译。因为向量被声明为常量,所以clear()函数无法操作,导致编译器发出错误信息。

**注意:**clear()删除了向量的所有元素。实际上,它把所有元素都标记为已删除,这样其他代码就可以占用它们的内存位置。如果任何元素的内存位置还没有被其他代码占用,那么这个元素仍然可以代表同一个向量重新使用。

矢量擦除

两个erase()成员函数的简化语法是。

    a.erase(q)

and

    a.erase(q1,q2)

其中a是向量的名称。

iterator erase(const_iterator position)

这是 "a.erase(q) "的完整语法。它返回一个指向元素的迭代器,这个元素就在被擦除的元素后面。参数q是一个指向要擦除的元素的迭代器。下面的程序说明了这一点。

#include <vector>

#include <iostream>

using namespace std;

 

int main()

{

    vector<char> vtr = {'P', 'Q', 'R', 'S', 'T', 'U'};

 

    vector<char>::iterator iter = vtr.begin();

    ++iter; ++iter;

 

    vector<char>::iterator it = vtr.erase(iter);

 

    for (int i=0; i < vtr.size(); i++) {

        cout << vtr[i] << ' ';

    }

    cout << endl;

 

    cout << *it << endl;

 

    return 0;

}

输出是

P Q S T U  
  
S

'R'已经被删除。返回的迭代器现在指向'S',它就在'R'之后。成员函数,begin(),返回一个指向向量第一个元素的迭代器。在代码中,这个迭代器被递增了两次,指向'R'。'R'被表达式 "vtr.erase(iter) "所擦除。

矢量中的范围

对于列表。

'P', 'Q', 'R', 'S', 'T', 'U'

的序列,'Q', 'R', 'S', 'T'是一个范围。然而,在C++容器中,最后一个元素,'T'不被认为是范围的一部分。这在一般情况下被表示为。

[i, j)

or

[q1, q2)

'['在这种情况下,意味着序列中的第一个元素被包括在内,而')'意味着最后一个元素不被包括在内。

iterator erase(const_iterator first, const_iterator last)

这是 "a.erase(q1,q2) "的完整语法。它返回一个指向元素的迭代器,这个元素正好在被擦除的范围后面。注意:范围内的最后一个元素没有被擦除。所以,返回的迭代器将指向该范围的最后一个元素。参数q1和q2是迭代器,指向范围内的第一个和最后一个元素。下面的程序说明了这一点。

#include <vector>

#include <iostream>

using namespace std;

 

int main()

{

    vector<char> vtr = {'P', 'Q', 'R', 'S', 'T', 'U'};

 

    vector<char>::iterator itB = vtr.begin();

    ++itB;

    vector<char>::iterator itE = vtr.end();

    --itE; --itE;

 

    vector<char>::iterator it = vtr.erase(itB, itE);

 

    for (int i=0; i < vtr.size(); i++) {

        cout << vtr[i] << ' ';

    }

    cout << endl;

 

    cout << *it << endl;

 

    return 0;

}

输出是

P T U  
  
T

'Q', 'R', 'S'已经被删除。返回的迭代器现在指向'T',它是容器范围内的最后一个元素。成员函数end()返回一个迭代器,该迭代器正好指向向量的最后一个元素之后。在代码中,这个迭代器被递减了两次,指向'T',即范围的最后一个元素。'Q', 'R', 'S'被删除,没有最后一个元素,'T'在范围内,表达式,"vtr.erase(itB, itE)"。

常态向量和 erase()

如果一个向量的声明前面有const,表示常数,那么它的元素都不能被删除。下面的程序将无法编译,对a.erase(q)表达式发出错误信息。

#include <vector>

#include <iostream>

using namespace std;

 

int main()

{

    const vector<char> vtr = {'P', 'Q', 'R', 'S', 'T', 'U'};

 

    vector<char>::const_iterator iter = vtr.begin();

    ++iter; ++iter;

 

    vector<char>::const_iterator it = vtr.erase(iter);

 

    for (int i=0; i < vtr.size(); i++) {

        cout << vtr[i] << ' ';

    }

    cout << endl;

 

    cout << *it << endl;

 

    return 0;

}

如果读者尝试这个程序,他将会收到一个错误信息。该程序将不会被编译。

下面的程序将无法编译,对a.erase(q1,q2)表达式发出错误信息。

#include <vector>

#include <iostream>

using namespace std;

 

int main()

{

    const vector<char> vtr = {'P', 'Q', 'R', 'S', 'T', 'U'};

 

    vector<char>::const_iterator itB = vtr.begin();

    ++itB;

    vector<char>::const_iterator itE = vtr.end();

    --itE; --itE;

 

    vector<char>::const_iterator it = vtr.erase(itB, itE);

 

    for (int i=0; i < vtr.size(); i++) {

        cout << vtr[i] << ' ';

    }

    cout << endl;

 

    cout << *it << endl;

 

    return 0;

}

注意: erase() 删除一个元素或一个元素的范围。实际上,它把一个元素标记为已删除,这样它们的内存位置就可以被其他代码占用了。如果任何元素的内存位置还没有被其他代码占用,那么这个元素仍然可以代表同一个向量重新使用。

pop_back()

pop_back()向量成员函数是一种擦除()函数。然而,它只删除了向量的最后一个元素。其语法为

void pop_back()

它不需要参数,并返回无效。下面的程序说明了它的用途。

#include <vector>

#include <iostream>

using namespace std;

 

int main()

{

    vector<char> vtr = {'P', 'Q', 'R', 'S', 'T', 'U'};

 

    vtr.pop_back();

 

    for (int i=0; i < vtr.size(); i++) {

        cout << vtr[i] << ' ';

    }

    cout << endl;

 

    return 0;

}

输出是

P Q R S T

最后一个元素,'U'已经被移除(擦除)。

销毁一个向量

一个向量可以被销毁吗?是的!但是,当一个向量被销毁时,除了它的名字之外,它的所有元素都被删除了;这意味着向量声明仍然可以被重新使用,但有一些不确定性。销毁一个向量的语法是。

a.~X()

其中'a'是向量的名称。下面的程序说明了这一点。

#include <vector>

#include <iostream>

using namespace std;

 

int main()

{

        vector<char> vtr = {'P', 'Q', 'R', 'S', 'T', 'U'};

 

        vtr.~vector();

 

        vtr = {'V', 'W', 'X', 'Y', 'Z'};

 

        for (int i=0; i < vtr.size(); i++) {

            cout << vtr[i] << ' ';

        }

        cout << endl;

 

        vtr.~vector();

 

        vtr.push_back('A');

        vtr.push_back('B');

        vtr.push_back('C');

        vtr.push_back('D');

        vtr.push_back('E');

 

        for (int i=0; i < vtr.size(); i++) {

            cout << vtr[i] << ' ';

        }

        cout << endl;

        return 0;

}

输出是

    V W X Y Z
    p ^ t e @ A  C D E

来自作者的计算机,第二行有一些不可靠的字符。

结论

向量成员函数clear()可以和向量成员函数erase()进行比较。clear()删除了向量中的所有元素。实际上,它把所有的元素都标记为已删除,这样它们的内存位置就可以被其他代码占用了。如果任何元素的内存位置还没有被其他代码占用,那么这个元素仍然可以代表同一个向量重新使用。 erase()删除一个元素或一个元素范围。实际上,它将一个元素标记为已删除,这样内存位置就可以被其他代码占用。如果任何被删除的元素的内存位置还没有被其他代码占用,那么这个元素仍然可以代表同一个向量被重新使用。 Clear与destroy, ~X()有相似之处。