std::vector簡介及其使用


本文中的vector指的是std::vector C++11標准。

 

Vector概述

template <class T,class Alloc = allocator <T> > class vector; //通用模板

  vector是表示可以改變大小的數組的序列容器。

  就像數組一樣,vector使用連續存儲空間存儲元素,這意味着它們的元素也可以使用指向其元素的指針進行偏移來訪問,並與數組一樣高效。但與數組不同的是, vector的大小可以動態變化,並且是由容器自動處理的。

  在內部實現上,vector使用動態分配的數組來存儲它們的元素。在插入新元素時,vector的大小增大,可能需要重新分配數組,這意味着可能要分配新數組並將原有數組中所有元素移動到這個新數組中。重新分配數組的時間成本相對高昂,因此,vector不會在每次向容器添加元素時都重新分配數組。vector容器可能會分配一些額外的存儲空間來適應可能的增長,因此容器的實際容量可能比其包含的元素個數要大。不同庫可以實現不同的增長策略以在使用現有內存和 重新分配內容之間取得平衡,但無論如何,重新分配內存時的數組大小應以對數增長,這樣在vector末端插入單個元素時就可以得到平攤的常數時間復雜度。

  因此,與數組相比,vector消耗更多內存,以換取以更有效的方式管理存儲空間。

  與其他動態序列容器(deques,lists和forward_lists)相比,vector可以非常高效地訪問其元素(就像數組一樣)並且相對高效地從其末尾添加或刪除元素。 對於涉及在末尾以外的位置插入或刪除元素的操作,性能比其他序列容器要差,並且與lists和forward_lists相比具有更少的迭代器和引用一致性。

 

容器屬性

  • 順序存儲

   序列容器中的元素按照嚴格的線性順序存儲。各個元素通過使用它們在這個序列中的位置(index)來訪問。

  • 動態數組

   允許直接訪問序列中的任何元素,支持指針運算,相對快速的添加/刪除序列末尾的元素。

  • 分配器

   容器使用allocator對象來動態處理其存儲需求。

 

模板參數

  • T 

  元素的類型。只有當 T 保證在移動操作時不會拋出異常,實現才會進行優化,即在重新分配數組時移動元素而不是復制它們。

  別名為成員類型 vector :: value_type。

  • Alloc

  用於定義分配模型的分配器對象的類型。默認情況下,使用allocator類模板,該模板定義最簡單的內存分配模型,並且與值無關。

  別名為成員類型 vector :: allocator_type。

 

成員類型

member type definition notes
value_type The first template parameter (T)  
allocator_type The second template parameter (Alloc) defaults to: allocator<value_type>
reference value_type&  
const_reference const value_type&  
pointer allocator_traits<allocator_type>::pointer for the default allocator: value_type*
const_pointer allocator_traits<allocator_type>::const_pointer for the default allocator: const value_type*
iterator a random access iterator to value_type convertible to const_iterator
const_iterator a random access iterator to const value_type  
reverse_iterator reverse_iterator<iterator>  
const_reverse_iterator reverse_iterator<const_iterator>  
difference_type a signed integral type, identical to: iterator_traits<iterator>::difference_type usually the same as ptrdiff_t
size_type an unsigned integral type that can represent any non-negative value of difference_type usually the same as size_t

 

成員函數

  •  (constructor) 構造函數
   
   
default (1)
explicit vector (const allocator_type& alloc = allocator_type());
fill (2)
explicit vector (size_type n);
         vector (size_type n, const value_type& val,
                 const allocator_type& alloc = allocator_type());
range (3)
template <class InputIterator>
  vector (InputIterator first, InputIterator last,
          const allocator_type& alloc = allocator_type());
copy (4)
vector (const vector& x);
vector (const vector& x, const allocator_type& alloc);
move (5)
vector (vector&& x);
vector (vector&& x, const allocator_type& alloc);
initializer list (6)
vector (initializer_list<value_type> il,
       const allocator_type& alloc = allocator_type());
default (1)
explicit vector (const allocator_type& alloc = allocator_type());
fill (2)
explicit vector (size_type n);
vector (size_type n, const value_type& val,
        const allocator_type& alloc = allocator_type());
range (3)
template <class InputIterator>
vector (InputIterator first, InputIterator last,
        const allocator_type& alloc = allocator_type());
copy (4)
vector (const vector& x);
vector (const vector& x, const allocator_type& alloc);
move (5)
vector (vector&& x);
vector (vector&& x, const allocator_type& alloc);
initializer list (6)
vector (initializer_list<value_type> il,
       const allocator_type& alloc = allocator_type());

   構造函數示例:

// constructing vectors
#include <iostream>
#include <vector>

int main ()
{
  // constructors used in the same order as described above:
  std::vector<int> first;                                // empty vector of ints
  std::vector<int> second (4,100);                       // four ints with value 100
  std::vector<int> third (second.begin(),second.end());  // iterating through second
  std::vector<int> fourth (third);                       // a copy of third

  // the iterator constructor can also be used to construct from arrays:
  int myints[] = {16,2,77,29};
  std::vector<int> fifth (myints, myints + sizeof(myints) / sizeof(int) );

  std::cout << "The contents of fifth are:";
  for (std::vector<int>::iterator it = fifth.begin(); it != fifth.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

Output:
The contents of fifth are: 16 2 77 29 
構造函數示例
  •  (destructor) 析構函數
~vector();
  • operator= 賦值
copy (1)
vector& operator= (const vector& x);
move (2)
vector& operator= (vector&& x);
initializer list (3)
vector& operator= (initializer_list<value_type> il);
  •  迭代器相關
函數 函數原型 功能描述
begin iterator begin() noexcept; Return iterator to   beginning 
const_iterator   begin() const noexcept;
end iterator end() noexcept; Return iterator to   end 
const_iterator   end() const noexcept;
rbegin reverse_iterator rbegin()   noexcept; Return reverse   iterator to reverse beginning 
const_reverse_iterator   rbegin() const noexcept;
rend reverse_iterator rend()   noexcept; Return reverse   iterator to reverse end 
const_reverse_iterator   rend() const noexcept;
cbegin  const_iterator cbegin() const   noexcept; Return const_iterator to   beginning 
cend  const_iterator cend() const noexcept; Return const_iterator to   end 
crbegin  const_reverse_iterator crbegin() const noexcept; Return const_reverse_iterator to   reverse beginning 
crend  const_reverse_iterator crend()   const noexcept; Return const_reverse_iterator to   reverse end 

   迭代器示例:

// vector::begin/end
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> myvector;
  for (int i=1; i<=5; i++)
    myvector.push_back(i);

  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it = myvector.begin() ; it != myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

Output:
myvector contains: 1 2 3 4 5
迭代器示例
  •  容器大小或容量相關
函數 函數原型 功能描述
size size_type size() const noexcept; Return size 
max_size size_type max_size() const   noexcept; Return maximum size 
resize void resize (size_type n); Change size 
void   resize (size_type n, const value_type& val);
capacity size_type capacity() const noexcept; Return size of allocated storage   capacity 
empty bool empty() const noexcept; Test whether vector is   empty 
reserve void reserve (size_type n); Request a change in   capacity 
shrink_to_fit  void shrink_to_fit(); Shrink to fit 

  示例:

// comparing size, capacity and max_size
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> myvector;

  // set some content in the vector:
  for (int i=0; i<100; i++)
    myvector.push_back(i);

  std::cout << "size: " << (int) myvector.size() << '\n';
  std::cout << "capacity: " << (int) myvector.capacity() << '\n';
  std::cout << "max_size: " << (int) myvector.max_size() << '\n';
  return 0;
}

A possible output for this program could be:
size: 100
capacity: 128
max_size: 1073741823
示例代碼
  • 成員訪問相關
函數 函數原型 功能描述
operator[] reference operator[] (size_type   n); Access element 
const_reference operator[] (size_type n) const;
at reference at (size_type n); Access element 
const_reference at (size_type n) const;
front reference front(); Access first   element 
const_reference front() const;
back reference back(); Access last   element 
const_reference back() const;
data  value_type* data() noexcept; Access data. Return value: A pointer to the first element in the array used internally by the vector.
const value_type* data() const noexcept;

  成員訪問示例:

// vector::operator[]
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> myvector (10);   // 10 zero-initialized elements

  std::vector<int>::size_type sz = myvector.size();

  // assign some values:
  for (unsigned i=0; i<sz; i++) myvector[i]=i;

  // reverse vector using operator[]:
  for (unsigned i=0; i<sz/2; i++)
  {
    int temp;
    temp = myvector[sz-1-i];
    myvector[sz-1-i]=myvector[i];
    myvector[i]=temp;
  }

  std::cout << "myvector contains:";
  for (unsigned i=0; i<sz; i++)
    std::cout << ' ' << myvector[i];
  std::cout << '\n';

  return 0;
}

Output:
myvector contains: 9 8 7 6 5 4 3 2 1 0
----------------------------------------------------------------------
// vector::at
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> myvector (10);   // 10 zero-initialized ints

  // assign some values:
  for (unsigned i=0; i<myvector.size(); i++)
    myvector.at(i)=i;

  std::cout << "myvector contains:";
  for (unsigned i=0; i<myvector.size(); i++)
    std::cout << ' ' << myvector.at(i);
  std::cout << '\n';

  return 0;
}

Output:
myvector contains: 0 1 2 3 4 5 6 7 8 9
----------------------------------------------------------------------
// vector::front
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> myvector;

  myvector.push_back(78);
  myvector.push_back(16);

  // now front equals 78, and back 16

  myvector.front() -= myvector.back();

  std::cout << "myvector.front() is now " << myvector.front() << '\n';

  return 0;
}

Output:
myvector.front() is now 62
----------------------------------------------------------------------
// vector::back
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> myvector;

  myvector.push_back(10);

  while (myvector.back() != 0)
  {
    myvector.push_back ( myvector.back() -1 );
  }

  std::cout << "myvector contains:";
  for (unsigned i=0; i<myvector.size() ; i++)
    std::cout << ' ' << myvector[i];
  std::cout << '\n';

  return 0;
}

Output:
myvector contains: 10 9 8 7 6 5 4 3 2 1 0
----------------------------------------------------------------------
// vector::data
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> myvector (5);

  int* p = myvector.data();

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

  std::cout << "myvector contains:";
  for (unsigned i=0; i<myvector.size(); ++i)
    std::cout << ' ' << myvector[i];
  std::cout << '\n';

  return 0;
}

Output:
myvector contains: 10 20 0 100 0
成員訪問示例
  • 添加、刪除等修改相關操作
函數 函數原型 功能描述
assign template <class InputIterator>
void assign (InputIterator first, InputIterator last);
Assign vector content. Assigns new contents to the vector, replacing its current contents, and modifying its size accordingly.
void assign (size_type n, const value_type& val);
void assign (initializer_list<value_type> il);
push_back void push_back (const value_type& val); Add element at the end 
void push_back (value_type&& val);
pop_back void pop_back(); Delete last element 
insert iterator insert (const_iterator position, const value_type& val); Insert elements. Return value: An iterator that points to the first of the newly inserted elements.
iterator insert (const_iterator position, size_type n, const value_type& val);
template <class InputIterator>
iterator insert (const_iterator position, InputIterator first, InputIterator last);
iterator insert (const_iterator position, value_type&& val);
iterator insert (const_iterator position, initializer_list<value_type> il);
erase iterator erase (const_iterator position); Erase elements 
iterator erase (const_iterator first, const_iterator last);
swap void swap (vector& x); Swap content 
clear void clear() noexcept; Clear content 
emplace  template <class...   Args>
iterator emplace (const_iterator position, Args&&... args);
Construct and insert   element 
emplace_back  template <class...   Args>
void emplace_back (Args&&... args);
Construct and insert element at   the end 

   示例:

// vector assign
#include <iostream>
#include <vector>

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';
  return 0;
}

Output:
Size of first: 7
Size of second: 5
Size of third: 3
----------------------------------------------------------------------
// inserting into a vector
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> myvector (3,100);
  std::vector<int>::iterator it;

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

  myvector.insert (it,2,300);

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

  std::vector<int> anothervector (2,400);
  myvector.insert (it+2,anothervector.begin(),anothervector.end());

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

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

  return 0;
}

Output:
myvector contains: 501 502 503 300 300 400 400 200 100 100 100
示例代碼
  • Allocator相關
函數 函數原型 功能描述
get_allocator allocator_type get_allocator()   const noexcept; Get allocator

 

重載的非成員函數

函數 函數原型 功能描述
relational operators template <class T, class Alloc>
bool operator== (const vector<T,Alloc>& lhs, const vector<T,Alloc>& rhs);
Relational operators for vector
template <class T, class Alloc>
bool operator!= (const vector<T,Alloc>& lhs, const vector<T,Alloc>& rhs);
template <class T, class Alloc>
bool operator<  (const   vector<T,Alloc>& lhs, const vector<T,Alloc>& rhs);
template <class T, class Alloc>
bool operator<= (const vector<T,Alloc>& lhs, const vector<T,Alloc>& rhs);
template <class T, class Alloc>
bool operator>  (const vector<T,Alloc>& lhs, const vector<T,Alloc>& rhs);
template <class T, class Alloc>
bool operator>= (const vector<T,Alloc>& lhs, const vector<T,Alloc>& rhs);
swap template <class T, class Alloc>
void swap (vector<T,Alloc>& x, vector<T,Alloc>& y);
Exchange contents of vectors

 

特例

函數 函數原型 功能描述
vector<bool> template <class T, class   Alloc = allocator<T> > class vector; // generic template
template <class Alloc> class vector<bool,Alloc>;   // bool specialization
Vector of bool

   注:vector<bool>使用不慎可能會出問題,一般都建議不要使用。

 

翻譯、參考:

  http://www.cplusplus.com/reference/vector/vector/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM