C++:vector、string、list、forward_list、deque、array的swap


1. vector的swap(list、forward_list、deque与之类似)

#include <iostream>
#include <vector>
using namespace std;
void show(int i, vector<int> &v1, vector<int> &v2, vector<int>::iterator i1, vector<int>::iterator i2, int &r1, int &r2, int *p1, int *p2);

int main()
{
   vector<int> v1(1, 1);
   vector<int> v2(2, 2);
   // 迭代器
   auto i1 = v1.begin();
   auto i2 = v2.begin();
   //引用
   int &r1 = *v1.begin();
   int &r2 = *v2.begin();
   //指针
   int *p1 = &(*v1.begin());
   int *p2 = &(*v2.begin());
   //输出
   show(0, v1, v2, i1, i2, r1, r2, p1, p2);
   //交换
   swap(v1, v2);
   //输出
   cout << "\n--------------------------------------------------" << endl;
   show(1, v1, v2, i1, i2, r1, r2, p1, p2);
   return 0;
}

void show(int i, vector<int> &v1, vector<int> &v2, vector<int>::iterator i1, vector<int>::iterator i2, int &r1, int &r2, int *p1, int *p2)
{
   if (i)
   {
       cout << "vector after:\n"
            << endl;
   }
   else
   {
       cout << "vector before:\n"
            << endl;
   }

   cout << "v1:";
   for (auto &a : v1)
   {
       cout << a << "(" << &a << ")\t";
   }

   cout << endl;
   cout << "i1->" << *i1 << "(" << &(*i1) << ")"
        << "\tr1->" << r1 << "(" << &r1 << ")"
        << "\tp1->" << *p1 << "(" << &(*p1) << ")" << endl;

   cout << "\nv2:";
   for (auto &a : v2)
   {
       cout << a << "(" << &a << ")\t";
   }
   cout << endl;

   cout << "i2->" << *i2 << "(" << &(*i2) << ")"
        << "\tr2->" << r2 << "(" << &r2 << ")"
        << "\tp2->" << *p2 << "(" << &(*p2) << ")" << endl;
}

vector交换过程图

运行结果

分析:

  1. 迭代器i1、引用r1、指针p1始终指向0x2c0f88,其值为1,保持不变;迭代器i2、引用r2、指针p2始终指向0x2c0f98,其值为2,保持不变 。
  2. swap时,v1与v2交换的是其元素的地址。v1首元素地址从0x2c0f88换为0x2c0f98,v2首元素地址从0x2c0f98换为0x2c0f88。

2. array的swap

#include <iostream>
#include <array>
using namespace std;
void show(int i, array<int, 2> &a1, array<int, 2> &a2, array<int, 2>::iterator i1, array<int, 2>::iterator i2, int &r1, int &r2, int *p1, int *p2);

int main()
{
    array<int, 2> a1{1, 1};
    array<int, 2> a2{2, 2};
    // 迭代器
    auto i1 = a1.begin();
    auto i2 = a2.begin();
    //引用
    int &r1 = *a1.begin();
    int &r2 = *a2.begin();
    //指针
    int *p1 = &(*a1.begin());
    int *p2 = &(*a2.begin());
    //输出
    show(0, a1, a2, i1, i2, r1, r2, p1, p2);
    //交换
    swap(a1, a2);
    //输出
    cout << "\n--------------------------------------------------" << endl;
    show(1, a1, a2, i1, i2, r1, r2, p1, p2);
    return 0;
}

void show(int i, array<int, 2> &a1, array<int, 2> &a2, array<int, 2>::iterator i1, array<int, 2>::iterator i2, int &r1, int &r2, int *p1, int *p2)
{
    if (i)
    {
        cout << "array after:\n"
             << endl;
    }
    else
    {
        cout << "array before:\n"
             << endl;
    }

    cout << "a1:";
    for (auto &a : a1)
    {
        cout << a << "(" << &a << ")\t";
    }

    cout << endl;
    cout << "i1->" << *i1 << "(" << &(*i1) << ")"
         << "\tr1->" << r1 << "(" << &r1 << ")"
         << "\tp1->" << *p1 << "(" << &(*p1) << ")" << endl;

    cout << "\na2:";
    for (auto &a : a2)
    {
        cout << a << "(" << &a << ")\t";
    }
    cout << endl;

    cout << "i2->" << *i2 << "(" << &(*i2) << ")"
         << "\tr2->" << r2 << "(" << &r2 << ")"
         << "\tp2->" << *p2 << "(" << &(*p2) << ")" << endl;
}

array交换过程图

运行结果

分析:

  1. 迭代器i1、引用r1、指针p1始终指向0x22feb0,但其值从1换为2;迭代器i2、引用r2、指针p2始终指向0x22fea8,但其值也从1换为2。
  2. swap时,a1与a2交换的是其元素的值。a1和a2首元素地址不变。

3. string的swap

#include <iostream>
#include <vector>
using namespace std;
void show(int i, string &s1, string &s2, string::iterator i1, string::iterator i2, char &r1, char &r2, char *p1, char *p2);

int main()
{
    string s1 = "a";
    string s2 = "bc";
    // 迭代器
    auto i1 = s1.begin();
    auto i2 = s2.begin();
    //引用
    char &r1 = *s1.begin();
    char &r2 = *s2.begin();
    //指针
    char *p1 = &(*s1.begin());
    char *p2 = &(*s2.begin());
    //输出
    show(0, s1, s2, i1, i2, r1, r2, p1, p2);
    //交换
    swap(s1, s2);
    //输出
    cout << "\n--------------------------------------------------" << endl;
    show(1, s1, s2, i1, i2, r1, r2, p1, p2);
    return 0;
}

void show(int i, string &s1, string &s2, string::iterator i1, string::iterator i2, char &r1, char &r2, char *p1, char *p2)
{
    if (i)
    {
        cout << "string after:\n"
             << endl;
    }
    else
    {
        cout << "string before:\n"
             << endl;
    }

    cout << "s1:";
    for (auto &a : s1)
    {
        cout << a << "(" << &a << ")\t";
    }

    cout << endl;
    cout << "i1->" << *i1 << "(" << &(*i1) << ")"
         << "\tr1->" << r1 << "(" << &r1 << ")"
         << "\tp1->" << *p1 << "(" << &(*p1) << ")" << endl;

    cout << "\ns2:";
    for (auto &a : s2)
    {
        cout << a << "(" << &a << ")\t";
    }
    cout << endl;

    cout << "i2->" << *i2 << "(" << &(*i2) << ")"
         << "\tr2->" << r2 << "(" << &r2 << ")"
         << "\tp2->" << *p2 << "(" << &(*p2) << ")" << endl;
}

运行结果

分析:

  1. string执行swap时,类似于vector,即只交换容器的内部数据结构。
  2. 因为string过短时,为其分配内存过于浪费,故将其存放在临时内存区域中,其元素地址与其它容器不同。string执行swap时,会将为string重新分配内存,从而造成迭代器、引用和指针失效。

4. 总结

  1. array执行swap时,真正交换对应的元素值;其它容器只交换其容器的内部数据结构(即元素地址)。
  2. array执行swap时,要求两个容器的容器类型、元素类型和元素个数相同;其它容器只要求容器类型和元素类型相同。
  3. string执行swap后,其指向容器元素的原迭代器、引用和指针失效;其它容器的原迭代器、引用和指针仍有效
发布了77 篇原创文章 · 获赞 25 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_34801642/article/details/105109990