一、容器vector

使用vector你必须包含头文件<vector>:

#include<vector>

型别vector是一个定义于namespace std内的template:

  1. template<class _Ty,
  2. class _Ax = allocator<_Ty> >

第二个參数定义内存模型。

我们一般採用默认的内存模型。

二、vector的功能

vector模塑出一个动态数组。vector将其元拷贝到内部的动态数组中。

元素之间总是存在某种顺序,它是一种有序群集。

支持随即存取。

它的迭代器是随机存取迭代器。所以对不论什么一个STL算法都奏效。

向vector加入一个元素或者删除当中的一个元素,其后的全部元素都要移动位置,每一次移动都要调用赋值操作符。

所以。在末端加入或删除元素,性能非常好。

可是在前段或者中部的话。性能较差。

vector优异性能的秘诀之中的一个是它配置比其所容纳的元素所需很多其它的内存。我们须要了解大小容量的关系。

函数size()能够返回vector的大小。即vector中实际元素的个数。

而capacity()返回容量。是当前的vector所实际可以容纳的元素的数量。它应该总是大于或者等于vector的大小。

假设须要向vector中放置比capacity很多其它的元素。则须要又一次配置内部存储器。

vector的容量也会随之增长。

看以下的演示样例代码:

  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4. #include <algorithm>
  5. using namespace std;
  6. int main()
  7. {
  8. vector<string> sentence(1);
  9. cout << "max_size():" << sentence.max_size() << endl;
  10. cout << "size():" << sentence.size() << endl;
  11. cout << "capacity():" << sentence.capacity() << endl;
  12. sentence.reserve(5);
  13. sentence.push_back("Hello,");
  14. sentence.push_back("how ");
  15. sentence.push_back("are ");
  16. sentence.push_back("you ");
  17. sentence.push_back("?");
  18. copy(sentence.begin(),sentence.end(),
  19. ostream_iterator<string>(cout," "));
  20. cout << endl;
  21. cout << "max_size():" << sentence.max_size() << endl;
  22. cout << "size():" << sentence.size() << endl;
  23. cout << "capacity():" << sentence.capacity() << endl;
  24. swap(sentence[1],sentence[3]);
  25. sentence.insert(find(sentence.begin(),sentence.end(),"?"),
  26. "always");
  27. sentence.back() = "!";
  28. copy(sentence.begin(),sentence.end(),
  29. ostream_iterator<string>(cout," "));
  30. cout << endl;
  31. cout << "max_size():" << sentence.max_size() << endl;
  32. cout << "size():" << sentence.size() << endl;
  33. cout << "capacity():" << sentence.capacity() << endl;
  34. }

执行结果:



在程序中。当再次向vector插入元素时。因为vector的容量不够,所以引起了内存的又一次分配。可是capacity()的结果与实作版本号有关,max_size也是。

vector的容量十分重要,是由于:

1、一旦内存又一次配置,与之相关的全部的reference、pointers、iterators都会失效。

2、内存配置非常费时。

解决问题的方法有:

1、能够使用reserve()保留适当容量,降低又一次配置内存的次数。演示样例代码:

  1. vector<string> sentence(1);
  2. sentence.reserve(50);

2、在初始化期间向构造函数传递附加參数。构造出足够的空间。

  1. vector<T> v(5);

当然,这样的元素的型别必须提供默认构造函数。可是假设元素的型别比較复杂,初始化操作也非常耗时。

假设仅仅是为了保留足够的内存。用法1较好。

注意:reserve不能缩减vector的容量。由此,我们能够知道。即使删除元素。其reference、pointers、iterators也会继续有效,指向动作发生前的位置。

可是插入操作可能使reference、pointers、iterators失效(由于可能会导致又一次配置空间)。

使用swap函数能够缩减vector容量。

由于两个vector交换内容后,他们的容量也会互换。

1、

  1. template<class T>
  2. void shrinkCapacity(vector<T> &v)
  3. {
  4. vector<T> tmp(v);
  5. v.swap(tmp);
  6. }

2、

  1. vector<T>(v).swap(v);

上面两种方法等价。

都是先构造出一个暂时vector对象,以v的元素进行初始化,再与v进行交换。

须要注意的是:暂时对象一般都是精确分配实际所需的内存。

所以可以起到减小vector容量的效果。

三、vector的操作函数

全部的构造函数和析构函数例如以下:

非变动性操作:

赋值操作:

上述操作进行的是将新元素赋值给vector,并将旧元素所有移除!演示样例代码:

  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4. #include <algorithm>
  5. using namespace std;
  6. int main()
  7. {
  8. vector<string> sentence(1);
  9. cout << "max_size():" << sentence.max_size() << endl;
  10. cout << "size():" << sentence.size() << endl;
  11. cout << "capacity():" << sentence.capacity() << endl;
  12. sentence.reserve(5);
  13. sentence.push_back("Hello,");
  14. sentence.push_back("how ");
  15. sentence.push_back("are ");
  16. sentence.push_back("you ");
  17. sentence.push_back("?

    ");

  18. copy(sentence.begin(),sentence.end(),
  19. ostream_iterator<string>(cout," "));
  20. cout << endl;
  21. sentence.assign(3,"new");
  22. copy(sentence.begin(),sentence.end(),
  23. ostream_iterator<string>(cout," "));
  24. cout << endl;
  25. }

执行结果:

能够看出原来的元素所有被删除了。

元素存取

在这几个函数中,唯一进行下标检查的是at函数。

因此。在调用operator[]的时候,必须心理清楚索引是否是有效的。

迭代器相关函数

迭代器失效的两种情况是:

1、在一个较小的位置上删除或者是移动元素。

2、因为容量的变换引起内存又一次分配。

插入和移除元素

插入和移除元素。都会使“作用点”之后的各元素的reference、pointers、iterators失效。插入操作还可能引发内存又一次分配,那么该容器上的全部的reference、pointers、iterators都会失效。

四、把vector当做一般数组使用

如今的C++标准保证vector的元素必须分布于连续空间中。对于vector中的一个合法索引,满足下列表达式:

&v[i] = &v[0] + i;

我们必须保证vector可以容纳全部数据。

假设使用的是C-String,记住最后有个'\0'。

仅仅要我们须要一个元素型别为T的数组,就能够採用vector<T>,然后传递第一个元素的地址给它。

注意:千万不要把迭代器当做第一元素的地址来传递。由于vector迭代器是由实作版本号定义的,不一定是一个一般指针。

  1. printf("%s",v.begin());//ERROR(might work,but not portable)
  2. printf("%s",&v[0]);//OK

STL源代码学习--vector用法汇总的更多相关文章

  1. STL源代码学习(vector篇)

    #include <concept_checks.h> #include<stl_allocate.h> /// The vector base class's constru ...

  2. C++ STL源代码学习(map,set内部heap篇)

    stl_heap.h ///STL中使用的是大顶堆 /// Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap ...

  3. C++ STL源代码学习之算法篇

    ///因为篇幅太长,因此,删去了非常多接口,仅仅分析了内部实现,算法对迭代器的要求也被删去 /// search. template <class _ForwardIter1, class _F ...

  4. C++ STL常用容器基本用法汇总

    1.vector 包含头文件#include<vector> 使用命名域using namespace std 定义元素类型为T的vector vector<T> vec 增: ...

  5. C++ STL源代码学习(list篇)

    ///STL list为双向循环链表 struct _List_node_base { _List_node_base* _M_next; _List_node_base* _M_prev; }; t ...

  6. C++ STL 源代码学习(之deque篇)

    stl_deque.h /** Class invariants: * For any nonsingular iterator i: * i.node is the address of an el ...

  7. C++STL源代码学习(之slist篇)

    ///stl_slist.h ///list为双向循环链表,slist为单向链表.某些操作效率更高 ///slist是SGI额外提供的单向链表,不属于C++标准 struct _Slist_node_ ...

  8. STL vector用法介绍

    STL vector用法介绍 介绍 这篇文章的目的是为了介绍std::vector,如何恰当地使用它们的成员函数等操作.本文中还讨论了条件函数和函数指针在迭代算法中使用,如在remove_if()和f ...

  9. STL中的Vector相关用法

    STL中的Vector相关用法 标准库vector类型使用需要的头文件:#include <vector>. vector 是一个类模板,不是一种数据类型,vector<int> ...

随机推荐

  1. Spring HandlerInterceptor的使用

    http://blog.csdn.net/joeyon1985/article/details/49903761

  2. HibernateCRUD基础框架(2)-HQL语句构造器(HqlQueryBuilder,HqlUpdateBuilder)

    上篇讲述了最基本的实体类,本篇接着讲述HQL语句构造器,包括查询和更新等. 优点:通过面向对象的方式构造HQL语句,更快捷,不需要手动拼接HQL. 缺点:封装可能降低性能,只能支持常用的和较为简单的H ...

  3. 【Educational Codeforces Round 31 B】Japanese Crosswords Strike Back

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 所有数字的和加上n-1,如果为x则唯一,否则不唯一 [代码] #include <bits/stdc++.h> usin ...

  4. iOS之StatusBar详解

    随便打开手机上的主流APP,我们不难发现它们的状态栏都是跟导航栏保持一致的背景颜色,如下图的微信和instagram: WECHAT.PNG INS.PNG 那么今天我们就来说一下StatusBar这 ...

  5. [转载]Surging 分布式微服务框架使用入门

    前言 本文非 Surging 官方教程,只是自己学习的总结.如有哪里不对,还望指正. 我对 surging 的看法 我目前所在的公司采用架构就是类似与Surging的RPC框架,在.NET 4.0框架 ...

  6. 【Codeforces Round #435 (Div. 2) B】Mahmoud and Ehab and the bipartiteness

    [链接]h在这里写链接 [题意] 让你在一棵树上,加入尽可能多的边. 使得这棵树依然是一张二分图. [题解] 让每个节点的度数,都变成二分图的对方集合中的点的个数就好. [错的次数] 0 [反思] 在 ...

  7. 数据结构与算法实验题 9.1 K 歌 DFS+剪枝

    数据结构与算法实验题 K 歌 ★实验任务 3* n 个人(标号1~ 3 * n )分成 n 组 K 歌.有 m 个 3 人组合,每个组合都对应一个分数,你能算出最大能够得到的总分数么? ★数据输入 输 ...

  8. 魔兽争霸war3心得体会(四):不死族vs人族1本火魔塔

    QQ对战平台上玩随机的人特别多,为了应对对方的"出其不意",我最近一直用小狗去探路,小狗在家采集30个木头-摆放商店,就可以去探路了.主要有几个好处:知道对方的种族-出生点位-开局 ...

  9. swift学习第一天:认识swift以及swift的常量和变量

    一:认识swift // 1.导入框架 //#import <UIKit/UIKit.h> import UIKit // 2.定义一个标识符 // int a = 10; // swif ...

  10. php实现求最小的k个数(日常出错很容易是分号或者$符号忘记写了)

    php实现求最小的k个数(日常出错很容易是分号或者$符号忘记写了) 一.总结 日常出错很容易是分号或者$符号忘记写了 二.php实现求最小的k个数 题目描述 输入n个整数,找出其中最小的K个数.例如输 ...