STL源代码学习--vector用法汇总

一、容器vector

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

#include<vector>

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

[cpp] view plaincopyprint?

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

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

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

二、vector的功能

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

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

支持随即存取。

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

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

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

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

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

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

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

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

vector的容量也会随之增长。

看以下的演示样例代码:

[cpp] view plaincopyprint?

  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()保留适当容量,降低又一次配置内存的次数。演示样例代码:

[cpp] view plaincopyprint">?

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

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

[cpp] view plaincopyprint">?

  1. vector<T> v(5);

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

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

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

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

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

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

1、

[cpp] view plaincopyprint">?

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

2、

[cpp] view plaincopyprint?

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

上面两种方法等价。

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

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

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

三、vector的操作函数

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

非变动性操作:

赋值操作:

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

[cpp] view plaincopyprint?

  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迭代器是由实作版本号定义的,不一定是一个一般指针。

[cpp] view plaincopyprint">?

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

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

STL中的Vector相关用法

STL中的Vector相关用法 标准库vector类型使用需要的头文件:#include <vector>. vector 是一个类模板,不是一种数据类型,vector<int>是一种数据类型. Vector的存储空间是连续的,list不是连续存储的. 1. 定义和初始化 vector< typeName > v1; //默认v1为空,故下面的赋值是错误的v1[0]=5;//v2是v1的一个副本,若v1.size()>v2.size()则赋值后v2.size()被

STL学习——Vector篇

STL学习--Vector篇 vector简介 vector的数据安排及操作方式与array非常相似,两者的区别在于空间运用的灵活性.array是静态空间,一旦配置了,就不能改变:要换个大(或小)一点的可以,但琐碎的事由客户端完成:首先配置一块新空间,然后将元素从旧址一一搬往新址,再把原来的空间释还给系统.而vector是动态空间,随着元素的加入,它的内部机制会自动扩充空间以容纳新元素.它对内存的合理利用和灵活运用有很大的帮助. vector实现关键技术:对大小的控制以及重新配置时的数据移动效率

C/C++解题常用STL大礼包 含vector,map,set,queue(含优先队列) ,stack的常用用法

每次忘记都去查,真难啊 1 /* 2 C/C++解题常用STL大礼包 含vector,map,set,queue(含优先队列) ,stack的常用用法 3 */ 4 5 /* 6 vector常用用法 7 */ 8 //头文件 9 #include<vector> 10 11 //常用的初始化方法 12 vector<int> v; //直接定义一个整型元素的向量 且未声明长度,其中int的位置可以换成别的数据类型或者结构体等 13 vector<int> v(10);

STL源代码分析——STL算法sort排序算法

前言 因为在前文的<STL算法剖析>中,源代码剖析许多,不方便学习,也不方便以后复习.这里把这些算法进行归类,对他们单独的源代码剖析进行解说.本文介绍的STL算法中的sort排序算法,SGI STL中的排序算法不是简单的高速排序,而是交叉利用各种排序:堆排序.插入排序和高速排序:这样做的目的是提高效率.针对数据量比較大的採用高速排序,数据量比較小的能够採用堆排序或插入排序. 本文介绍了有关排序的算法random_shuffle.partition.stable_partition.sort.s

[转载]机器学习&amp;深度学习经典资料汇总,全到让人震惊

自学成才秘籍!机器学习&深度学习经典资料汇总 转自:中国大数据: http://www.thebigdata.cn/JiShuBoKe/13299.html [日期:2015-01-27] 来源:亚马逊  作者: [字体:大 中 小] 小编都深深的震惊了,到底是谁那么好整理了那么多干货性的书籍.小编对此人表示崇高的敬意,小编不是文章的生产者,只是文章的搬运工. <Brief History of Machine Learning> 介绍:这是一篇介绍机器学习历史的文章,介绍很全面,从感

STL list链表的用法详解(转)

本文以List容器为例子,介绍了STL的基本内容,从容器到迭代器,再到普通函数,而且例子丰富,通俗易懂.不失为STL的入门文章,新手不容错过! 0 前言 1 定义一个list 2 使用list的成员函数push_back和push_front插入一个元素到list中 3 list的成员函数empty() 4 用for循环来处理list中的元素 5 用STL的通用算法for_each来处理list中的元素 6 用STL的通用算法count_if()来统计list中的元素个数 7 使用count_i

stl容器学习——queue,stack,list与string

目录 string stack queue list 点击上面的内容可以实现跳转哦 简介:本文记录了对string list queue stack四个容器的学习总结,包含有四种容器常用的函数介绍和一些使用过程中碰到的细节总结,在list容器中介绍了迭代器的使用. 头文件 想要用哪一种容器,就要加上对应的头文件 比如想要使用queue , 就要加上 #include<queue> 以此类推,想要使用STL库中的容器,只要加上它们的头文件就好. string 目录部分 1.string的定义及初

win7下vs2010编译调试stl源代码

平台环境:windows 7 32位+VS2010+STL源代码5.2.1 STL在sourceforge下载,如果不可以下载,可以在csdn下载. 下载好源码后,首先解压到硬盘,我解压到D:\STL. 在vs2010 tools选择“Visual Studio 命令提示(VS2010)” 在cmd窗口,目录切换到刚刚解压源码的根目录, 输入configure -help查看编译选项 显示平台式XP,这里暂时不管. 输入configure msvc9配置环境 上面红框里面的内容不用去管. 之后切

C#中DllImport用法汇总

(转) 最近使用DllImport,从网上google后发现,大部分内容都是相同,又从MSDN中搜集下,现将内容汇总,与大家分享. 大家在实际工作学习C#的时候,可能会问:为什么我们要为一些已经存在的功能(比如Windows中的一些功能,C++中已经编写好的一些方法)要重新编写代码,C#有没有方法可以直接都用这些原本已经存在的功能呢?答案是肯定的,大家可以通过C#中的DllImport直接调用这些功能. DllImport是System.Runtime.InteropServices命名空间下的