一、vector的接口

vector是一个类模板,这也就意味着可以存储各种类型。vector底层是一个数组,一个顺序容器。
接下来就看看vector的接口。
1. 构造函数
//用n个val构造vector对象
explicit vector (size_type n, const value_type& val = value_type(),const allocator_type& alloc = allocator_type());
//用一段迭代器区间构造vector对象
template <class InputIterator>
vector (InputIterator first, InputIterator last,const allocator_type& alloc = allocator_type());
//拷贝构造
vector (const vector& x);

2. 赋值运算符重载
//用一个vector对象赋值给另一个vector对象
vector& operator= (const vector& x);

3. 迭代器
//分为普通迭代器,const版本迭代器,反向迭代器
//begin指向空间的起始位置
iterator begin();
const_iterator begin() const;
//end指向尾后位置
iterator end();
const_iterator end() const;
//反向迭代器,rbegin指向末尾
reverse_iterator rbegin();
const_reverse_iterator rbegin() const;
//rend指向空间起始位置的前一个位置
reverse_iterator rend();
const_reverse_iterator rend() const;


4. 容量
//返回vector中元素的个数
size_type size() const;
//n < size(),保留前n个元素,其余删除
//n > size(), 插入元素到n个数据
//n > capacity(),会扩容
void resize (size_type n, value_type val = value_type());
//vector的容量
size_type capacity() const;
//判空
bool empty() const noexcept;
//n > capacity(),申请空间到n个或者更大
//其它情况,不会申请空间,vector的容量没有影响
void reserve (size_type n);
//缩容,请求容器的容量适应size的大小(不一定等于size,可能会大于)
void shrink_to_fit();

5. 访问元素
//访问n位置上的元素,并返回其引用
reference operator[] (size_type n);
const_reference operator[] (size_type n) const;
//访问第一个元素
reference front();
const_reference front() const;
//访问最后一个元素
reference back();
const_reference back() const;

6. 修改
//赋值,用一个vector的内容去代替当前的内容,修改它的size
template <class InputIterator>
//用一段迭代器区间去赋值
void assign (InputIterator first, InputIterator last);
//用n个val去赋值
void assign (size_type n, const value_type& val);
//用初始化列表去赋值
void assign (initializer_list<value_type> il);
那么,什么才是初始化列表呢?

初始化列表也是C++库里面的一个类模板。它的构造函数包含一个 initializer_list() noexcept ,还有3个成员函数。
//返回初始化列表中的元素个数
size_t size() const noexcept;
//返回初始化列表中第一个元素的指针
const T* begin() const noexcept;
//返回初始化列表最后一个元素后一个位置的指针
const T* end() const noexcept;

//尾插
void push_back (const value_type& val);
//尾删
void pop_back();
//在pos位置之前插入元素
iterator insert (const_iterator position, const value_type& val);
//在pos位置插入n个元素
iterator insert (const_iterator position,size_type n, const value_type& val);
//在pos位置插入一段迭代器区间
template <class InputIterator>
iterator insert (const_iterator position,InputIterator first, InputIterator last);
//在pos位置插入一个初始化列表
iterator insert (const_iterator position,initializer_list<value_type> il);
//删除单个元素或者一段迭代器区间的元素
iterator erase (const_iterator position);
iterator erase (const_iterator first, const_iterator last);
//交换两个vector对象的内容
void swap (vector& x);
//删除所有的元素
void clear() noexcept;

7. 友元函数
//比较两个vector对象的大小,逐元素进行比较,如果vector的size相等并且所有元素相等,那就 == ,如果所有的元素相等,但size不相等,size大的vector大。
(1) template <class T, class Alloc>
bool operator== (const vector<T,Alloc>& lhs, const vector<T,Alloc>& rhs);
(2) template <class T, class Alloc>
bool operator!= (const vector<T,Alloc>& lhs, const vector<T,Alloc>& rhs);
(3) template <class T, class Alloc>
bool operator< (const vector<T,Alloc>& lhs, const vector<T,Alloc>& rhs);
(4) template <class T, class Alloc>
bool operator<= (const vector<T,Alloc>& lhs, const vector<T,Alloc>& rhs);
(5) template <class T, class Alloc>
bool operator> (const vector<T,Alloc>& lhs, const vector<T,Alloc>& rhs);
(6) template <class T, class Alloc>
bool operator>= (const vector<T,Alloc>& lhs, const vector<T,Alloc>& rhs);

8. 如何理解C++中的二维数组,如何使用C语言动态开辟二维数组?
迭代器也是有类型的。可以观察到在insert函数中,使用了模板,模板参数是InputIterator,其实迭代器还有种类。

Input、Output代表输入输出,Forward代表单向迭代器,Bidirectional代表双向迭代器,Random Access代表随机迭代器。
那么,这些迭代器有什么区别呢?
Forward只支持++操作,Bidirectional支持++,--操作,Random Access支持++,--,+,-操作。
那为什么有这么多的迭代器类型呢?



可以看到,有些函数要求传递单向迭代器,有的需要双向迭代器,有的需要随机迭代器。所以,需要不同的迭代器类型。
能够传递单向迭代器的函数也能够传递双向迭代器,当然也能够传随机迭代器,因为单向迭代器支持的++操作,其它迭代器也支持呀,同理,传双向迭代器的函数也能够传随机迭代器。
看到这里,大家对于vector已经有了一定的了解了。那么,在C语言中,有一维数组,二维数组,在C++中呢?
我们知道vector的底层是一个数组,那么,如何用C++的方式去表示一个二维数组呢?很简单,vector<vector<T>>就可以表示了。其中T是模板参数。
该如何理解呢?
假设vector中的成员变量以下几个
template<class T>
class vector
{
private:
T* _start;//空间的起始地址
size_t _size;//存储元素的个数
size_t _capacity;//空间的容量
};
假设存储的是整型数据,那么vector<vector<int>>就是这样子的,用图来理解一下吧。

这不就是一个二维数组吗!用下标+[]访问的时候其实就是调用了两次operator[]运算符重载函数。
vector<vector<int>> vv;//定义一个vv对象
1.vv[i][j]就可以访问对应位置的数据了,和C语言访问二维数组
的方式是一样的,但是底层原理是不一样的。
2.C++访问二维数组是调用了两次operator[]运算符重载函数,第
一次调用,返回的是一个vector<int>对象的引用,第二次是由这
个返回值调用运算符重载函数的,返回二维数组里的数据。
3.C语言访问二维数组的方式其实就是一次解引用,因为二维数组其实在逻辑上就是一维数组,地址空间是连续的,所以只需要用空间的起始地址+偏移量再解引用即可。
那么如何用C语言的方式动态开辟一个二维数组呢?

那么,使用动态开辟的二维数组,访问数据时又是怎么理解原理呢?
其实是通过两次解引用的方式访问数据的,第一次解引用访问的是一个指针,该指针指向一段数组空间,第二次也是通过(起始地址+偏移量)的方式解引用访问到数据的。
转载自CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/2402_84532723/article/details/151080902



