C++ STL 序列式容器<vector>入门(一)

本文深入探讨了C++ STL中的vector容器,包括初始化、成员函数、非成员函数、迭代器操作及实例演示,如reserve、shrink_to_fit、数据访问、assign、insert等,为读者提供了全面的vector使用指南。

c++ STL序列式容器(sequence containers)之vector


内容来自自己的胡编乱造以及STL源码剖析以及c++ reference,每次看都要翻译太麻烦了.


vector属于STL 顺序容器的一种,数据的安排以及操作方式与array极其相似.唯一的差别就在空间运用的灵活性,其存储由容器自动处理。用的时候一定要包含头文件#include <vector>

<一>vector初始化

首先是vector初始化方式,这里代码用C++ reference自带的例程:

#include <iostream>
#include <vector>
using namespace std;
int main ()
{
  // constructors used in the same order as described above:
  vector<int> first;                                // 定义元素类型为int的空数组;
  vector<int> second (4,100);                       // 4个元素,初始值为100;
  vector<int> third (second.begin(),second.end());  // 利用second的迭代器初始化third数组;
  vector<int> fourth (third);                       // 拷贝初始化

  // 迭代器构造函数也可用于从数组构造:
  int myints[] = {16,2,77,29};
  vector<int> fifth (myints, myints + sizeof(myints) / sizeof(int) );

  cout << "fifth的内容是:";
  for (vector<int>::iterator it = fifth.begin(); it != fifth.end(); ++it)
    cout << ' ' << *it;
    cout <<endl;

  return 0;
}

<二>vector成员函数和非成员函数

  • 迭代器

    函数名注释
    begin返回指向vector中第一个元素的迭代器.
    end返回指向vector中最后一个元素之后位置的迭代器
    rbegin返回指向vector中最后一个元素的迭代器,即反向开始的第一个
    rend返回指向vector中第一个元素之前位置的迭代器
    cbegin返回指向容器中第一个元素的const_iterator。自己可以增加或者减少但是不能用它去修改元素,即使元素类型不是const
    cend返回指向容器中第一个元素的const_iterator。
    crbegin返回指向vector中最后一个元素的const型迭代器
    crend返回指向vector中第一个元素之前位置的const迭代器
  • capacity

    函数名注释
    size返回vector大小(元素个数)
    max_size返回vector可容纳的最大元素个数
    resize参数n,调整vector大小使其包含n个元素,小于当前大小的话保留前n个元素
    capacity当前分配的存储容量的大小,以其可以容纳的元素数量来衡量。可以用reserve更改
    empty测试vector是否为空,为空返回true,否则返回false.ps:要清除vector请看clear.
    reserve请求vector容量至少足以包含n个元素。如果请求的大小大于最大大小(vector :: max_size),则抛出length_error异常。
    shrink_to_fit缩小到适合大小
  • 元素访问

    函数名注释
    操作符[]返回对vector容器中位置n处元素的引用。第一个元素位置是0.不检查边界
    at返回对vector中位置n处元素的引用。 该函数自动检查n是否在vector中的有效元素的范围内,如果不是,则抛出out_of_range异常。
    front返回对vector中第一个元素的引用。(begin()返回的是迭代器,即指针)
    back返回对vector中第一个元素的引用。
    data返回指向vector内部使用的数组中第一个元素的指针。
  • 修改

    函数名注释
    assign将新内容分配给矢量,替换其当前内容,并相应地修改其大小。在调用之前容器中保存的任何元素都被销毁并被新构造的元素替换(不会发生元素的赋值)
    push_back在vector的末尾添加一个新元素,在其最后一个元素之后。
    pop_back删除最后一个元素
    insert在指定的元素之前插入新元素.5种方式
    erase删除,参数为一个迭代器的直接删除单个元素,或者两个迭代器,[first,last)删除范围内的元素,返回值为删除的最后一个元素之后的一个位置
    swap用x的内容交换容器的内容,x是另一个相同类型的vector对象。大小可能不同。
    clear从vector中删除所有元素(被销毁),使容器的大小为0。与此容器相关的所有迭代器,指针和引用都将失效。
    emplace构造和插入元素,返回值为一个指向新放置元素的迭代器,参数为position和args
    emplace_back在vector的末尾插入一个新元素,紧跟在当前最后一个元素之后。
  • 分配器

    get_allocator :获取分配器,返回与vector关联的allocator对象的副本 .

  • 非成员函数重载

    relational operators常用操作符
    swap容器x的内容与y的内容交换。两个容器对象必须具有相同的类型(相同的模板参数),尽管大小可能不同。在调用此成员函数之后,x中的元素是在调用之前在y中的元素,y的元素是在x中的元素。所有迭代器,引用和指针对交换的对象仍然有效。

<三>代码区域

reserve代码示例

// vector::reserve
#include <iostream>
#include <vector>
using namespace std;
int main ()
{
  vector<int>::size_type sz;

  vector<int> foo;
  sz = foo.capacity();
  cout << "making foo grow:\n";
  for (int i=0; i<100; ++i) {
    foo.push_back(i);
    if (sz!=foo.capacity()) {
      sz = foo.capacity();
      cout << "capacity changed: " << sz << '\n';
    }
  }

  vector<int> bar;
  sz = bar.capacity();
  bar.reserve(100);   // 和上面唯一不同的地方
  cout << "making bar grow:\n";
  for (int i=0; i<120; ++i) {
    bar.push_back(i);
    if (sz!=bar.capacity()) {
      sz = bar.capacity();
      cout << "capacity changed: " << sz << '\n';
    }
  }
  return 0;
}

shrink代码示例

// vector::shrink_to_fit
#include <iostream>
#include <vector>
using namespace std;
int main ()
{
  vector<int> myvector (100);
  cout << "1. capacity of myvector: " << myvector.capacity() << endl;

  myvector.resize(10);
  cout << "2. capacity of myvector: " << myvector.capacity() << '\n';

  myvector.shrink_to_fit();
  cout << "3. capacity of myvector: " << myvector.capacity() << '\n';

  return 0;
} 

data数据代码示例

// vector::data
#include <iostream>
#include <vector>
using namespace std;
int main ()
{
  vector<int> myvector (5);

  int* p = myvector.data();

  *p = 10;
  ++p;
  *p = 20;
  p[2] = 100;

  cout << "myvector 包含:";
  for (unsigned i=0; i<myvector.size(); ++i)
    cout << ' ' << myvector[i];
  cout <<endl;

  return 0;
}

assign三种传参数的方式

     1.范围(first,last)
         序列中的初始位置和最终位置。使用的范围为[first,last),前包后不包。
     2.填充(n,val)
         n是容器的新尺寸,类型size_type是无符号整形,val是填充的内容.类型是容器中元素的类型.

     3.初始化列表
         一个initializer_list(c++11)对象,编译器会根据initializer list声明的自动构造函数构造此类对象.

initializer list 代码示例

// initializer_list example
#include <iostream>          // std::cout
#include <vector>
#include <initializer_list>  // std::initializer_list
using namespace std;
int main ()
{
std::vector<int> first;
  std::vector<int> second;
  std::vector<int> third;

  first.assign (7,100);             // 7 ints with a value of 100

  std::vector<int>::iterator it;
  it=first.begin()+1;

  second.assign (it,first.end()-1); // the 5 central values of first

  int myints[] = {1776,7,4};
  third.assign (myints,myints+3);   // assigning from array.

  std::cout << "Size of first: " << int (first.size()) << '\n';
  std::cout << "Size of second: " << int (second.size()) << '\n';
  std::cout << "Size of third: " << int (third.size()) << '\n';


  initializer_list<int> mylist;
  vector<int> tmp;
  mylist = { 10, 20, 30 };
  cout << "mylist contains:";
  for (int x: mylist) 
     cout << ' ' << x;
     cout << endl;
  tmp.assign(mylist);
  cout << "my vector tmp contains:";
  for(auto i:tmp)
  {
  cout<<" "<<i;
  }
  cout<<endl;
  return 0;
}

output:

Size of first: 7
Size of second: 5
Size of third: 3
mylist contains: 10 20 30
my vector tmp contains: 10 20 30

insert五种方式

五种的返回值都是指向第一个新插入元素的迭代器。
1.迭代器插入(单一元素)
函数声明: iterator insert (const_iterator position, const value_type& val);
2.迭代器插入(填充)
函数声明:iterator insert (const_iterator position, size_type n, const value_type& val);
3.范围插入
函数声明:template <class InputIterator>
iterator insert (const_iterator position, InputIterator first, InputIterator last);
//前包后不包
4.move
函数声明:iterator insert (const_iterator position, value_type&& val);
5.initializer_list
函数声明:iterator insert (const_iterator position, initializer_list<value_type> il);
insert插入代码示例:

// inserting into a vector
#include <iostream>
#include <vector>
using namespace std;
int main ()
{
   vector<int> myvector (3,100);//初始化三个100,即:100,100,100
   vector<int>::iterator it;

  it = myvector.begin();
  it = myvector.insert ( it , 200 );//200,100,100,100

  myvector.insert (it,2,300);//300,300,200,100,100,100

  // "it" no longer valid, get a new one:
  it = myvector.begin();

   vector<int> anothervector (2,400);
  myvector.insert (it+2,anothervector.begin(),anothervector.end());//300,300,400,400,200,100,100,100

  int myarray [] = { 501,502,503 };
  myvector.insert (myvector.begin(), myarray, myarray+3);

   cout << "myvector contains:";
  for (it=myvector.begin(); it<myvector.end(); it++)
     cout << ' ' << *it;
   cout <<endl;

  return 0;
}

output

myvector包含:501 502 503 300 300 400 400 200 100 100 100
// swap vectors
#include <iostream>
#include <vector>
using namespace std;
int main ()
{
   vector<int> foo (3,100);   // three ints with a value of 100
   vector<int> bar (5,200);   // five ints with a value of 200

  foo.swap(bar);

   cout << "foo contains:";
  for (unsigned i=0; i<foo.size(); i++)
     cout << ' ' << foo[i];
   cout << endl;

   cout << "bar contains:";
  for (unsigned i=0; i<bar.size(); i++)
     cout << ' ' << bar[i];
   cout <<endl;

  return 0;
}

output:

foo contains: 200 200 200 200 200 
bar contains: 100 100 100

get_allocator

分配器是定义标准库的某些部分使用的内存模型的类,更具体地说,是由STL容器使用的类。
成员函数:

(constructor)构造allocator对象
(destructor)分配器析构函数
address返回地址
allocate分配存储块
deallocate释放存储块
max_size可分配最大大小
construct构造一个对象
destroy销毁对象

这里代码里vector的元素类型为int,可能不够直观,可以将元素类型换成自定义的class。

代码:

// vector::get_allocator
#include <iostream>
#include <vector>
using namespace std;
int main ()
{
   vector<int> myvector;
  int * p;
  unsigned int i;

  // allocate an array with space for 5 elements using vector's allocator:
  p = myvector.get_allocator().allocate(5);

  // construct values in-place on the array:
  for (i=0; i<5; i++) myvector.get_allocator().construct(&p[i],i);

   cout << "The allocated array contains:";
  for (i=0; i<5; i++)  
   cout << ' ' << p[i];
   cout <<endl;

  // destroy and deallocate:
  for (i=0; i<5; i++) myvector.get_allocator().destroy(&p[i]);
  myvector.get_allocator().deallocate(p,5);

  return 0;
}

output:
The allocated array contains: 0 1 2 3 4

operator操作符重载

  1. ==
  2. !=
  3. <
  4. <=
  5. >
  6. >=
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值