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`类源码的分析。

