STL源码刨析_vector
发布人:shili8
发布时间:2024-12-22 19:59
阅读次数:0
**STL源码分析——vector**
在C++标准模板库(STL)中,`vector`是最常用的容器之一。它提供了一个动态数组的实现,使得我们可以轻松地添加或删除元素,而不需要担心内存管理的问题。在本文中,我们将深入分析`vector`的源码,并且会展示一些示例代码。
**1. vector类定义**
首先,让我们看一下`vector`类的定义:
cpptemplate <typename T> class vector { public: typedef T value_type; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef T& reference; typedef const T& const_reference; // 构造函数和析构函数 explicit vector(size_type n =0); vector(const vector& x); ~vector(); // 赋值运算符 vector& operator=(const vector& x); // 元素访问 reference at(size_type n); const_reference at(size_type n) const; reference operator[](size_type n); const_reference operator[](size_type n) const; // 元素插入和删除 void push_back(const T& x); void pop_back(); iterator insert(iterator pos, const T& x); iterator erase(iterator pos); // 其他成员函数 size_type size() const; size_type max_size() const; size_type capacity() const; void reserve(size_type n); void resize(size_type n); };
从上面的定义中,我们可以看到`vector`类提供了以下功能:
* 构造函数和析构函数* 赋值运算符* 元素访问(`at()`、`operator[]()`)
* 元素插入和删除(`push_back()`、`pop_back()`、`insert()`、`erase()`)
* 其他成员函数(`size()`、`max_size()`、`capacity()`、`reserve()`、`resize()`)
**2. 构造函数和析构函数**
下面是`vector`类的构造函数和析构函数:
cpptemplate <typename T> vector<T>::vector(size_type n) : _M_impl(new _Alloc::rebind<_Alloc, T>::other(_M_impl)) { if (n >0) { _M_impl->push_back(T()); } } template <typename T> vector<T>::vector(const vector& x) : _M_impl(x._M_impl ? new _Alloc::rebind<_Alloc, T>::other(*x._M_impl) :0) {} template <typename T> vector<T>::~vector() { if (_M_impl) { _M_impl->clear(); delete _M_impl; } }
从上面的代码中,我们可以看到:
* 构造函数首先创建一个`_Alloc::rebind<_Alloc, T>::other()`对象,然后将其赋值给 `_M_impl`成员变量。如果传入的参数 `n` 大于0,则会在 `_M_impl` 中添加一个元素。
* 赋值构造函数首先检查 `_M_impl` 是否为 nullptr,如果是则创建一个新的 `_Alloc::rebind<_Alloc, T>::other()` 对象,然后赋值给 `_M_impl`。
* 析构函数首先检查 `_M_impl` 是否为 nullptr,如果是则直接返回。如果 `_M_impl` 不为 nullptr,则会清除 `_M_impl` 中的元素,然后释放 `_M_impl`。
**3. 元素访问**
下面是`vector`类的元素访问成员函数:
cpptemplate <typename T> T& vector<T>::at(size_type n) { if (n >=0 && n < _M_impl->size()) { return (*_M_impl)[n]; } throw out_of_range(); } template <typename T> const T& vector<T>::at(size_type n) const { if (n >=0 && n < _M_impl->size()) { return (*_M_impl)[n]; } throw out_of_range(); }
从上面的代码中,我们可以看到:
* `at()`成员函数首先检查传入的参数 `n` 是否在 `_M_impl` 中的范围内,如果是则返回对应元素的引用。如果不在范围内,则抛出 `out_of_range()` 异常。
* `const at()`成员函数与 `at()`成员函数类似,但返回的是 const 引用。
**4. 元素插入和删除**
下面是`vector`类的元素插入和删除成员函数:
cpptemplate <typename T> void vector<T>::push_back(const T& x) { _M_impl->push_back(x); } template <typename T> void vector<T>::pop_back() { if (_M_impl->size() >0) { _M_impl->pop_back(); } }
从上面的代码中,我们可以看到:
* `push_back()`成员函数首先检查 `_M_impl` 中是否有元素,如果没有则直接返回。如果有元素,则在 `_M_impl` 中添加一个新元素。
* `pop_back()`成员函数首先检查 `_M_impl` 中是否有元素,如果没有则直接返回。如果有元素,则从 `_M_impl` 中删除最后一个元素。
**5. 其他成员函数**
下面是`vector`类的其他成员函数:
cpptemplate <typename T> size_type vector<T>::size() const { return _M_impl->size(); } template <typename T> size_type vector<T>::max_size() const { return _M_impl->max_size(); } template <typename T> size_type vector<T>::capacity() const { return _M_impl->capacity(); } template <typename T> void vector<T>::reserve(size_type n) { if (n >0 && n <= _M_impl->max_size()) { _M_impl->reserve(n); } }
从上面的代码中,我们可以看到:
* `size()`成员函数返回 `_M_impl` 中元素的数量。
* `max_size()`成员函数返回 `_M_impl` 可容纳的最大元素数量。
* `capacity()`成员函数返回 `_M_impl` 当前可容纳的元素数量。
* `reserve()`成员函数首先检查传入的参数 `n` 是否在 `_M_impl` 的范围内,如果是则将 `_M_impl` 的容量设置为 `n`。
以上就是对`vector`类源码的分析。