## 💞💞 前言

hello hello~ ，这里是大耳朵土土垚~💖💖 ，欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹

💥个人主页：大耳朵土土垚的博客
💥 所属专栏：C++入门至进阶

## vector模拟实现完整代码

``````#pragma once
#include<iostream>
using namespace std;
#include<assert.h>
#define _CRT_SECURE_NO_WARNINGS 1
namespace tutu
{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;}//构造函数//拷贝构造,深拷贝vector(const vector<T>& v){//提前预留空间reserve(v.capacity());for (auto i : v){push_back(i);}}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():_start(nullptr), _finish(nullptr), _end_of_storage(nullptr){}//迭代器区间初始化//函数模板template<class InputIterator>vector(InputIterator first, InputIterator last){while (first != last){push_back(*first);++first;}}//n个val构造vector(size_t n, const T& val = T())//缺省值不能给0，因为T可能是string，所以给匿名对象{reserve(n);while (n--){push_back(val);}}//n个val构造重载，第一个参数为int类型vector(int n, const T& val = T())//缺省值不能给0，因为T可能是string，所以给匿名对象{reserve(n);while (n--){push_back(val);}}//initializer_list构造vector(initializer_list<T> il){reserve(il.size());for (auto i : il){push_back(i);}}//析构函数~vector(){if (_start){delete[] _start;_start = _finish = _end_of_storage = nullptr;}}//容量size_t capacity() const{return _end_of_storage - _start;}//数据个数size_t size()	const{return _finish - _start;}//扩容void reserve(size_t n){if (n > capacity()){size_t oldsize = _finish - _start;T* tmp = new T[n];//memcpy(tmp, _start, oldsize * sizeof(T));	//拷贝数据,浅拷贝对于string类等不适用if (_start)//如果_start为空就不需要拷贝数据{for (size_t i = 0; i < oldsize; i++){tmp[i] = _start[i];//使用赋值来实现深拷贝}}delete[] _start;	//释放旧的空间_start = tmp;_finish = _start + oldsize;_end_of_storage = _start + n;}}//尾插void push_back(const T& x){/*if (_finish == _end_of_storage){size_t newcapacity = capacity() == 0 ? 4 : 2 * capacity();reserve(newcapacity);}*_finish = x;++_finish;*/insert(end(), x);}T& operator[](size_t pos){assert(pos < size());return _start[pos];}//const对象使用const T& operator[](size_t pos) const{assert(pos < size());return _start[pos];}//尾删void pop_back(){if (_finish != _start)//判断是否为空{--_finish;}}//插入iterator insert(iterator pos, const T& x){//防止迭代器因为后面的扩容失效，所以要提前记录pos位置size_t pos_size = pos - _start;//断言防止越界assert(pos_size <= size());assert(pos_size >= 0);//看是否扩容if (_finish == _end_of_storage){size_t newcapacity = capacity() == 0 ? 4 : 2 * capacity();reserve(newcapacity);}//如果扩容，pos可能会失效，所以要更新pospos = begin() + pos_size;//往后挪动数据iterator cur = _finish;while (cur != pos){*cur = *(cur - 1);cur--;}//插入数据*pos = x;_finish++;return pos;}//删除iterator erase(iterator pos){size_t pos_size = pos - _start;//断言防止越界assert(pos >= _start);assert(pos < _finish);//往前挪动数据iterator cur = pos;while (cur != _finish - 1){*cur = *(cur + 1);cur++;}_finish--;//更新pospos = _start + pos_size;return pos;}private:iterator _start = nullptr;iterator _finish = nullptr;iterator _end_of_storage = nullptr;};//测试代码尾插和[]void vectortest1(){vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);v1.push_back(4);v1.push_back(4);v1.push_back(4);for (int i = 0; i < v1.size(); i++){cout << v1[i] << " ";}cout << endl;}//迭代器测试void vectortest2(){vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);int* it = v1.begin();//指定类域 //int* it  = v1.begin();//也可以while (it != v1.end()){cout << *it << " ";it++;}}//范围for测试void vectortest3(){vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);for (auto i : v1){cout << i << " ";}}//插入删除数据测试void vectortest4(){vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);v1.insert(v1.begin(), 0);v1.erase(v1.begin());v1.erase(v1.end() - 1);for (auto i : v1){cout << i << " ";}}//n个val测试代码1void vectortest5(){vector<string> s1(10);//使用缺省值vector<string> s2(10, "hello");for (auto i : s1){cout << i << " ";}cout << endl;for (auto i : s2){cout << i << " ";}}//n个val测试代码2void vectortest6(){vector<int> v1(4, 2);for (auto i : v1){cout << i << " ";}}//initializer_list构造测试void vectortest7(){vector<int> v1({ 1,2,3,4,5 });vector<int> v2 = { 6,7,8,9,10 };for (auto i : v1){cout << i << " ";}cout << endl;for (auto i : v2){cout << i << " ";}}//扩容测试代码void vectortest8(){vector<string> s1;s1.push_back("1111111111111");s1.push_back("1111111111111");s1.push_back("1111111111111");s1.push_back("1111111111111");s1.push_back("1111111111111");s1.push_back("1111111111111");for (auto i : s1){cout << i << " ";}}
}
``````

## 1.vector成员变量

``````#include<iostream>
using namespace std;namespace tutu
{template<class T>class vector{public:typedef T* iterator;	//将T*typedef成iteratorprivate:iterator _start = nullptr;	//这里给缺省值iterator _finish = nullptr;iterator _end_of_storage = nullptr;}
};
``````

## 2.尾插push_back()

``````void push_back(const T& x)
{//判断容量是否够用if (_finish == _end_of_storage){size_t newcapacity = capacity() == 0 ? 4 : 2 * capacity();//扩容reserve(newcapacity);}//插入数据*_finish = x;_finish++;
}
``````

🥳🥳有关容量和数据个数的函数：

``````//容量
size_t capacity() const
{return _end_of_storage - _start;
}//数据个数
size_t size()	const
{return _finish - _start;
}
``````

## 3.扩容reserve()

``````void reserve(size_t n)
{if (n > capacity()){size_t oldsize = _finish - _start;	//记录大小T* tmp = new T[n];memcpy(tmp, _start, oldsize*sizeof(T));	//拷贝数据delete[] _start;	//释放旧的空间_start = tmp;_finish = _start + oldsize;_end_of_storage = _start + n;}
}
``````

## 4.operate[]

``````T& operator[](size_t pos)
{assert(pos < size());	//断言return _start[pos];
}
``````

``````//const对象使用
const T& operator[](size_t pos) const
{assert(pos < size());return _start[pos];
}
``````

## 5.析构函数

``````~vector()
{if (_start){delete[] _start;_start = _finish = _end_of_storage = nullptr;}
}
``````

### ✨测试代码

``````void vectortest1()
{vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);for (int i = 0; i < v1.size(); i++){cout << v1[i] << " ";}cout << endl;
}
``````

## 6.迭代器

``````//迭代器
iterator begin()
{return _start;
}iterator end()
{return _finish;
}``````

### const迭代器

``````const_iterator begin() const
{return _start;
}const_iterator end() const
{return _finish;
}
``````

### ✨迭代器测试代码

``````//迭代器测试
void vectortest2()
{vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);vector<int>::iterator it = v1.begin();//指定类域 //T* it  = v1.begin();//也可以while (it != v1.end()){cout << *it << " ";it++;}
}
``````

``````//范围for
void vectortest3()
{vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);for (auto i : v1){cout << i << " ";}
}
``````

## 7.插入insert()

``````//插入
iterator insert(iterator pos,const T& x)
{//防止迭代器因为后面的扩容失效，所以要提前记录pos位置size_t pos_size = pos - _start;//断言防止越界assert(pos_size <= size());assert(pos_size >= 0);//看是否扩容if (_finish == _end_of_storage){size_t newcapacity = capacity() == 0 ? 4 : 2 * capacity();reserve(newcapacity);}//如果扩容，pos可能会失效，所以要更新pospos = begin() + pos_size;//往后挪动数据iterator cur = _finish;while (cur != pos){*cur = *(cur - 1);cur--;}//插入数据*pos = x;_finish++;return pos;//返回更新后的迭代器
}
``````

🥳🥳有了插入函数之后尾插push_back()就可以使用insert()来实现啦，代码如下：

``````//尾插
void push_back(const T& x)
{insert(end(), x);
}
``````

## 8.删除erase()

``````//删除
iterator erase(iterator pos)
{size_t pos_size = pos - _start;//断言防止越界assert(pos >= _start);assert(pos < _finish);//往前挪动数据iterator cur = pos;while (cur != _finish - 1){*cur = *(cur + 1);cur++;}_finish--;//更新pospos = _start + pos_size;return pos;
}
``````

erase()之后迭代器失效问题

• 有可能删除之后缩容
• 删除最后一个位置会导致越界访问

### ✨插入删除测试代码

``````//插入删除数据
void vectortest4()
{vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);v1.insert(v1.begin(), 0);v1.erase(v1.begin());v1.erase(v1.end()-1);for (auto i : v1){cout << i << " ";}
}
``````

## 9.构造函数

### ✨拷贝构造

``````//拷贝构造,深拷贝
vector(const vector<T>& v)
{//提前预留空间reserve(v.capacity());for (auto i : v){push_back(i);}
}
``````

### 拷贝构造测试代码

``````void vectortest5()
{vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);vector<int> v2(v1);//用v1拷贝构造v2for (auto i : v2){cout << i << " ";}
}
``````

### ✨默认构造

``````//默认构造
vector():_start(nullptr),_finish(nullptr),_end_of_storage(nullptr)
{}
``````

### ✨迭代器区间初始化

``````//迭代器区间初始化
//函数模板
template<class InputIterator>
vector(InputIterator first, InputIterator last)
{while (first != last){push_back(*first);++first;}}
``````

### ✨n个val构造

``````//n个val构造
vector(size_t n, const T& val=T())//缺省值不能给0，因为T可能是string，所以给匿名对象
{reserve(n);while (n--){push_back(val);}
}
``````

### n个val构造测试代码

``````void vectortest5()
{vector<string> s1(10);//使用缺省值vector<string> s2(10, "hello");for (auto i : s1){cout << i << " ";}cout << endl;for (auto i : s2){cout << i << " ";}
}
``````

``````//n个val测试代码
void vectortest6()
{vector<int> v1(4, 2);for (auto i : v1){cout << i << " ";}
}
``````

``````//n个val构造重载，第一个参数为int类型
vector(int n, const T& val = T())//缺省值不能给0，因为T可能是string，所以给匿名对象
{reserve(n);while (n--){push_back(val);}
}
``````

### ✨initializer_list构造

initializer_list是C++新增的一个类型，方便初始化，支持将花括号括起来的值给initializer_list，initializer_list对象里面有两个指针，指向花括号里面值开始和结尾的下一个，并支持迭代器，所以可以使用范围for来遍历，当然这个要编译器支持将花括号传给它

``````//initializer_list构造
vector(initializer_list<T> il)
{reserve(il.size());//size表示数据个数for (auto i : il){push_back(i);}
}
``````

### initializer_list构造测试代码

C++11引入

``````//initializer_list构造测试
void vectortest7()
{隐式类型转换vector<int> v1({ 1,2,3,4,5 });	vector<int> v2={ 6,7,8,9,10 };	for (auto i : v1){cout << i << " ";}cout << endl;for (auto i : v2){cout << i << " ";}
}
``````

## 10.赋值运算符重载

``````//赋值运算符重载
vector<T>& operator=(vector<T> v)
{swap(v);return *this;
}
``````

🥳🥳swap函数

``````void swap(vector<T>& v)
{std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_end_of_storage, v._end_of_storage);}
``````

## 11.reserve()扩容存在的问题

### ✨测试代码

``````//扩容测试代码
void vectortest8()
{vector<string> s1;s1.push_back("1111111111111");s1.push_back("1111111111111");s1.push_back("1111111111111");s1.push_back("1111111111111");s1.push_back("1111111111111");s1.push_back("1111111111111");for (auto i : s1){cout << i << " ";}
}
``````

``````//扩容
void reserve(size_t n)
{if (n > capacity()){size_t oldsize = _finish - _start;T* tmp = new T[n];//memcpy(tmp, _start, oldsize * sizeof(T));	//拷贝数据,浅拷贝对于string类等不适用if (_start)//如果_start为空就不需要拷贝数据{for (size_t i = 0; i < oldsize; i++){tmp[i] = _start[i];//使用赋值来实现深拷贝}}delete[] _start;	//释放旧的空间_start = tmp;_finish = _start + oldsize;_end_of_storage = _start + n;}
}
``````

## 结语

### #12松桑前端后花园周刊-SolidStart、Vercel融资、Angular18、Nextjs15RC、p5.js、ChromeDevTools引入AI

⚡️行业动态 SolidStart 1.0 元框架发布 Solidjs 核心团队发布其元框架 SolidStart 1.0 正式版&#xff0c;其特点如下&#xff1a;基于文件系统的路由&#xff1b;支持SSR、流式SSR、CSR、SSG渲染模式&#xff1b;通过代码分割、树摇和无用代码删除构建优化&#xff1b;基于…

### 课时138：变量进阶_变量实践_综合案例

2.1.3 综合案例 学习目标 这一节&#xff0c;我们从 免密认证、脚本实践、小结 三个方面来学习 免密认证 案例需求 A 以主机免密码认证 连接到 远程主机B我们要做主机间免密码认证需要做三个动作1、本机生成密钥对2、对端机器使用公钥文件认证3、验证手工演示 本地主机生成…

### ajax快速入门

1 Ajax介绍 1概念&#xff1a; Asynchronous JavaScript And XML&#xff0c;异步的JavaScript和XML。 2作用&#xff1a; 数据交换&#xff1a;通过Ajax可以给服务器发送请求&#xff0c;并获取服务器响应的数据。 异步交互&#xff1a;可以在不重新加载整个页面的情况下&…