
🎬 博主名称 :键盘敲碎了雾霭
🔥 个人专栏 : 《C语言》《数据结构》 《C++》 《Matlab》 《Python》
⛺️指尖敲代码,雾霭皆可破

文章目录
- 一、vector常用接口
-
- [1.1 构造函数](#1.1 构造函数)
- [1.2 reserve](#1.2 reserve)
- [1.3 resize](#1.3 resize)
- [1.4 insert](#1.4 insert)
- [1.5 erase](#1.5 erase)
- 二、string与vector
-
- [2.1 区别](#2.1 区别)
- [2.2 注意点](#2.2 注意点)
- 三、Vector模拟实现
-
- [3.1 核心成员变量](#3.1 核心成员变量)
- [3.2 迭代器](#3.2 迭代器)
- [3.3 核心接口实现](#3.3 核心接口实现)
-
- [3.3.1 reserve](#3.3.1 reserve)
- 3.3.2push_back
- [3.3.3 insert](#3.3.3 insert)
- [3.3.4 erase](#3.3.4 erase)
- [3.3.5 resize](#3.3.5 resize)
- [3.4 构造与析构](#3.4 构造与析构)
-
- [3.4.1 默认构造](#3.4.1 默认构造)
- [3.4.2 迭代器区间构造(模板泛型)](#3.4.2 迭代器区间构造(模板泛型))
- [3.4.3 拷贝构造](#3.4.3 拷贝构造)
- [3.4.4 赋值运算符](#3.4.4 赋值运算符)
- [3.4.5 析构函数](#3.4.5 析构函数)
- [3.5 辅助接口](#3.5 辅助接口)
- [3.6 泛型打印函数](#3.6 泛型打印函数)
- 四、代码实现
一、vector常用接口
以下为成员函数
1.1 构造函数

cpp
vector<int> v1;
vector<int> v2(10,1);
vector<int> v3(++v2.begin(), --v2.end());
vector<int> v4(v2);
- 遍历的三种方式
cpp
for (int i = 0; i < v3.size(); i++)
{
cout << v3[i] << " ";
}
cout << endl;
vector<int>::iterator vit = v3.begin();
while (vit != v3.end())
{
cout << *vit << " ";
vit++;
}
cout << endl;
for (auto tmp : v3)
{
cout << tmp << " ";
}
cout << endl;
1.2 reserve

reserve不会缩容(与string里的reserve不同,与平台无关)
cpp
vector<int> v;
v.reserve(100);
size_t size = v.capacity();
for (int i = 0; i < 100; i++)
{
v.push_back(i);
if (size!=v.capacity())
{
size = v.capacity();
cout << size << endl;
}
}
vs按1.5倍扩容,会取整
1.3 resize

修改size,空间不够就扩容,不会缩容

cpp
int main()
{
vector<int> v1(10, 1);
v1.reserve(20);
cout << v1.size() << endl;
cout << v1.capacity() << endl;
v1.resize(15, 2);
cout << v1.size() << endl;
cout << v1.capacity() << endl;
v1.resize(25, 4);
cout << v1.size() << endl;
cout << v1.capacity() << endl;
v1.resize(5);
cout << v1.size() << endl;
cout << v1.capacity() << endl;
}
1.4 insert

不支持下标(用迭代器间接支持的)了,只支持迭代器
cpp
vector<int> v(10, 1);
v.push_back(2);
v.insert(v.begin(), 6);
v.insert(v.begin()+3, 6);
for (auto e : v)
{
cout << e << " ";
}
1.5 erase

同样也不支持下标
二、string与vector
2.1 区别
- vector没有流提取与流插入(<<、>>)
- 两者不能相互替代
- string可以返回c_str()并且有'\0'可以返回字符串,而vector没有
- string支持用ASCII码表比较大小
- string支持常量初始化,多了substr()、to_string()等其他函数
............等
2.2 注意点
vector还可以存储自定义类型
- string
cpp
vector<string> v;
string s1("hahaha");
v.push_back(s1);
v.push_back("xxx");
for (auto e : v)
{
cout << e << endl;
}
return 0;
- 二维数组
cpp
vector<int> a(5,1);
vector<vector<int>> b(10, a);
三、Vector模拟实现
vector 底层本质是一个动态数组,能够自动管理内存,在元素超过容量时自动扩容。
3.1 核心成员变量
只需三个指针即可完整管理整个数组:
cpp
template<class T>
class vector {
private:
iterator _start = nullptr; // 指向数据起始位置
iterator _finish = nullptr; // 指向最后一个有效数据的下一个位置
iterator _end_of_storage = nullptr; // 指向容量末尾的下一个位置
};
通过指针运算得到常用属性:
size() = _finish - _startcapacity() = _end_of_storage - _start
3.2 迭代器
cpp
iterator begin() { return _start; }
iterator end() { return _finish; }
const_iterator begin() const { return _start; }
const_iterator end() const { return _finish; }
3.3 核心接口实现
3.3.1 reserve
cpp
void reserve(size_t n) {
if (n > capacity()) {
iterator tmp = new T[n];
size_t old_size = size();
// 逐个拷贝 ------ 保证深拷贝
for (size_t i = 0; i < old_size; i++)
tmp[i] = _start[i];
delete[] _start;
_start = tmp;
_finish = tmp + old_size;
_end_of_storage = tmp + n;
}
}
⚠️ 关键点 :使用循环赋值而非
memcpy,确保自定义类型的深拷贝正确性。
3.3.2push_back
cpp
void push_back(const T& x) {
if (_finish == _end_of_storage) {
// 扩容策略:空容器分配4,否则翻倍
reserve(empty() ? 4 : 2 * capacity());
}
*_finish++ = x;
}
3.3.3 insert
cpp
iterator insert(iterator pos, const T& x) {
assert(pos >= _start && pos <= _finish);
size_t offset = pos - _start; // 保存偏移量
if (_finish == _end_of_storage) {
reserve(empty() ? 4 : 2 * capacity());
}
pos = _start + offset; // 重新定位
// 从后往前移动元素
for (iterator it = _finish - 1; it >= pos; --it)
*(it + 1) = *it;
*pos = x;
++_finish;
return pos; // 返回新位置,解决迭代器失效
}
3.3.4 erase
cpp
iterator erase(iterator pos) {
assert(pos >= _start && pos < _finish);
for (iterator it = pos + 1; it != _finish; ++it)
*(it - 1) = *it;
--_finish;
return pos; // 返回删除位置的下一个元素
}
3.3.5 resize
cpp
void resize(size_t n, const T& val = T()) {
if (n < size()) {
_finish = _start + n;
} else {
reserve(n);
while (_finish < _start + n)
*_finish++ = val;
}
}
3.4 构造与析构
3.4.1 默认构造
cpp
vector() = default; // 指针已在声明时初始化为 nullptr
3.4.2 迭代器区间构造(模板泛型)
cpp
template<class InputIterator>
vector(InputIterator first, InputIterator last) {
while (first != last)
push_back(*first++);
}
3.4.3 拷贝构造
cpp
vector(const vector<T>& other) {
reserve(other.size());
for (const auto& x : other)
push_back(x);
}
3.4.4 赋值运算符
cpp
vector<T>& operator=(const vector<T>& other) {
if (this != &other) {
clear();
reserve(other.size());
for (const auto& x : other)
push_back(x);
}
return *this;
}
3.4.5 析构函数
cpp
~vector() {
delete[] _start;
_start = _finish = _end_of_storage = nullptr;
}
3.5 辅助接口
cpp
T& operator[](size_t n) {
assert(n < size());
return _start[n];
}
const T& operator[](size_t n) const {
assert(n < size());
return _start[n];
}
size_t size() const { return _finish - _start; }
size_t capacity() const { return _end_of_storage - _start; }
bool empty() const { return _finish == _start; }
void clear() { _finish = _start; }
void pop_back() { assert(!empty()); --_finish; }
3.6 泛型打印函数
cpp
template<typename Container>
void print(const Container& c, const char* sep = " ") {
for (const auto& x : c)
cout << x << sep;
cout << endl;
}
四、代码实现
cpp
#pragma once
#include<iostream>
#include<assert.h>
#include<string>
using namespace std;
namespace A
{
template<class T>
class vector
{
public:
typedef T* iterator;
typedef const T* const_iterator;
iterator begin()
{
return _start;
}
iterator end()
{
return _finish;
}
const_iterator begin()const
{
return _start;
}
const_iterator end()const
{
return _finish;
}
void reserve(size_t n)
{
if (n > capacity())
{
iterator tmp = new T[n];
size_t old_size = size();
//memcpy(tmp, _start, sizeof(T) * size());
for (size_t i = 0; i < size(); i++)
{
tmp[i] = _start[i];
}
delete[] _start;
_start = tmp;
_finish = tmp + old_size;
_end_of_storage = tmp + n;
}
}
void clear()
{
_finish = _start;
}
vector<T>& operator=(const vector<T>& v)
{
if (&v != this)
{
clear();
reserve(v.size());
for (auto& e : v)
{
push_back(e);
}
}
return *this;
}
//void swap(vector<T>& v)
//{
// std::swap(_start, v._start);
// std::swap(_finish, v._finish);
// std::swap(_end_of_storage, v._end_of_storage);
//}
//vector<T> operator=(vector<T> v)
//{
// swap(v);
// return *this;
//}
vector() = default;
vector(const vector<T>& v)
{
reserve(v.size());
for (size_t i = 0; i < v.size(); i++)
{
push_back(v[i]);
}
}
~vector()
{
if (_start)
{
delete[] _start;
}
_finish = _end_of_storage = _start = nullptr;
}
size_t size()const
{
return _finish - _start;
}
size_t capacity()const
{
return _end_of_storage - _start;
}
T& operator[](size_t n)const
{
assert(n < size());
return _start[n];
}
void push_back(const T& x)
{
if (_end_of_storage == _finish)
{
reserve(capacity()==0 ? 4 : capacity() * 2);
}
*_finish = x;
_finish++;
}
void pop_back()
{
_finish--;
}
iterator insert(iterator pos, const T& x)
{
if (_end_of_storage == _finish)
{
size_t len = pos - _start;
reserve(capacity() == 0 ? 4 : capacity() * 2);
pos = _start + len;
}
auto end = _finish - 1;
while (end >= pos)
{
*(end + 1) = *end;
end--;
}
*pos = x;
_finish++;
return pos;
}
iterator erase(iterator pos)
{
auto it = pos + 1;
while (it!=_finish)
{
*(it - 1) = *it;
it++;
}
_finish--;
return pos;
}
void resize(size_t n,const T& val=T())
{
if (n < size())
{
_finish = _start + n;
}
else
{
reserve(n);
size_t len = _start+n-_finish;
while (len--)
{
push_back(val);
}
}
}
template<class Contain_iterator>
vector(Contain_iterator start, Contain_iterator finish)
{
while (start!=finish)
{
push_back(*start);
start++;
}
}
template<class Contain>
void print_contain(Contain& v)
{
for (size_t i = 0; i < v.size(); i++)
{
cout << v[i] << " ";
}
cout << endl;
for (auto ch : v)
{
cout << ch << " ";
}
cout << endl;
auto it = v.begin();
while (it != v.end())
{
cout << *it << " ";
it++;
}
cout << endl;
}
vector(size_t n, const T& val = T())
{
reserve(n);
for (size_t i = 0; i < n; i++)
{
push_back(val);
}
}
vector(int n, const T& val = T())
{
reserve(n);
for (size_t i = 0; i < n; i++)
{
push_back(val);
}
}
private:
iterator _start=nullptr;
iterator _finish=nullptr;
iterator _end_of_storage=nullptr;
};
void test();
void test01();
void test03();
}
# 文章结语
感谢你读到这里~我是「**键盘敲碎了雾霭**」,愿这篇文字帮你敲开了技术里的小迷雾 💻
如果内容对你有一点点帮助,不妨给个暖心三连吧👇
👍 **点赞** | ❤️ **收藏** | ⭐ **关注**
(听说三连的小伙伴,代码一次编译过,bug绕着走~)
你的支持,就是我继续敲碎技术雾霭的最大动力 🚀
🐶 小彩蛋:
/^ ^\
/ 0 0 \
V\ Y /V
/ - \
/ |
V__) ||
摸一摸毛茸茸的小狗,赶走所有疲惫和bug~我们下篇见 ✨