pc网站 手机网站 微网站/sem是什么电镜

pc网站 手机网站 微网站,sem是什么电镜,creative建网站平台,东莞房价最新消息文章目录 1. 引言2. vector的核心设计3. vector的常用接口介绍3.1 构造函数和析构函数3.1.1 默认构造函数3.1.2 带初始容量的构造函数3.1.3 析构函数 3.2 拷贝构造函数和拷贝赋值运算符3.2.1 拷贝构造函数3.2.2 拷贝赋值运算符 3.5 数组长度调整和动态扩容3.5.1 调整大小&#…

文章目录

  • 1. 引言
  • 2. vector的核心设计
  • 3. vector的常用接口介绍
    • 3.1 构造函数和析构函数
      • 3.1.1 默认构造函数
      • 3.1.2 带初始容量的构造函数
      • 3.1.3 析构函数
    • 3.2 拷贝构造函数和拷贝赋值运算符
      • 3.2.1 拷贝构造函数
      • 3.2.2 拷贝赋值运算符
    • 3.5 数组长度调整和动态扩容
      • 3.5.1 调整大小(resize)
      • 3.5.2 缩减容量(shrink_to_fit)
      • 3.5.3 动态扩容(reserve)
    • 3.6 添加元素
      • 3.6.1 添加左值元素
      • 3.6.2 添加右值元素
    • 3.7 删除元素
      • 3.7.1 删除指定位置元素
      • 3.7.2 尾删
    • 3.8 元素访问
      • 3.8.1 通过下标访问元素
    • 3.9 迭代器支持
  • 4. 总结
  • 5. 附录
    • 5.1 测试用例

1. 引言

std::vector 是 C++ 中最常用的动态数组容器。为了更好地理解其内部机制,我们将从头实现一个功能更完整的 vector,并逐步优化它。本文不仅会实现基本功能,还会深入探讨一些高级特性,例如异常安全性、迭代器支持和自定义分配器。

2. vector的核心设计

根据 STLvector 的设计。一个 vector 的核心是动态数组,它需要以下成员变量:

  • _start :指向动态数组当前存储元素的第一个位置。
  • _finish :指向动态数组当前存储元素的最后一个位置。
  • _end_of_storage :指向动态数组容量的最后一个位置。

具体的代码实现路径如下:

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(){}//类模板的成员函数,也可以是一个函数模板template <class InputIterator>vector(InputIterator first,InputIterator last){while (first != last){push_back(*first);++first;}}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 (int i = 0; i < n; i++){push_back(val);}}*/vector(std::initializer_list<T> il){reserve(il.size());for (auto& e : il){push_back(e);}}vector(const vector<T>& v){reserve(v.capacity());for (auto& e : v){push_back(e);}}void swap(vector<T>& tmp){// std 需要在上面将 std域展开std::swap(_start, tmp._start);std::swap(_finish, tmp._finish);std::swap(_endofstorage, tmp._endofstorage);}vector<T>& operator=(vector<T> v){swap(v);return *this;}~vector(){if (_start){delete[] _start;_start = _finish = _endofstorage = nullptr;}}T& operator[](size_t i){assert(i < size());return _start[i];}const T& operator[](size_t i) const{assert(i < size());return _start[i];}size_t size() const{return _finish - _start;}size_t capacity() const{return _endofstorage - _start;}void resize(size_t n, T val = T()){if (n <= size()){_finish = _start + n;}else{reserve(n);while (_finish < _start + n){*_finish = val;++_finish;}}}void reserve(size_t n){if (n > capacity()){size_t oldSize = size();T* tmp = new T[n];if (_start){for (size_t i = 0; i < oldSize; i++){tmp[i] = _start[i];}delete[] _start;}_start = tmp;_finish = _start + oldSize;_endofstorage = _start + n;}}void push_back(const T& x){insert(_finish, x);}bool empty(){return _start == _finish;}void pop_back(){assert(!empty());--_finish;}iterator insert(iterator pos,const T& x){assert(pos >= _start && pos <= _finish);if (_finish == _endofstorage){size_t len = pos - _start;reserve(capacity() == 0 ? 4 : capacity() * 2);pos = _start + len;}iterator i = _finish - 1;while (i >= pos){*(i + 1) = *i;--i;}*pos = x;++_finish;return pos;}iterator erase(iterator pos){assert(pos >= _start && pos < _finish);iterator i = pos + 1;while (i < _finish){*(i - 1) = *i;++i;}_finish--;return pos;}private:iterator _start = nullptr;iterator _finish = nullptr;iterator _endofstorage = nullptr;
};

3. vector的常用接口介绍

3.1 构造函数和析构函数

3.1.1 默认构造函数

初始化一个空的 vector

template <typename T>
Vector<T>::Vector() : (nullptr), size(0), capacity(0) {}

3.1.2 带初始容量的构造函数

允许用户指定初始容量。

template <typename T>
Vector<T>::Vector(size_t initial_capacity): data(new T[initial_capacity]), size(0), capacity(initial_capacity) {}

3.1.3 析构函数

释放动态分配的内存。

template <typename T>
Vector<T>::~Vector() {delete[] data;
}

3.2 拷贝构造函数和拷贝赋值运算符

3.2.1 拷贝构造函数

深拷贝另一个 vector 的内容。

template <typename T>
Vector<T>::Vector(const Vector& other): data(new T[other.capacity]), size(other.size), capacity(other.capacity) {for (size_t i = 0; i < size; ++i) {data[i] = other.data[i]; // 调用 T 的拷贝构造函数}
}

3.2.2 拷贝赋值运算符

先释放当前资源,再深拷贝另一个 vector 的内容。

template <typename T>
Vector<T>& Vector<T>::operator=(const Vector& other) {if (this != &other) {// 创建一个临时对象Vector temp(other);// 交换当前对象和临时对象的内容std::swap(data, temp.data);std::swap(size, temp.size);std::swap(capacity, temp.capacity);}return *this;
}

3.5 数组长度调整和动态扩容

3.5.1 调整大小(resize)

resize 函数用于调整 vector 的大小。如果新大小大于当前容量,则需要扩容;如果新大小小于当前大小,则只需调整 size

template <typename T>
void Vector<T>::resize(size_t new_size) {if (new_size > capacity) {// 如果新大小大于当前容量,需要扩容reserve(new_size);}if (new_size > size) {// 如果新大小大于当前大小,初始化新增元素for (size_t i = size; i < new_size; ++i) {data[i] = T(); // 使用默认构造函数初始化新元素}}size = new_size; // 更新大小
}

3.5.2 缩减容量(shrink_to_fit)

shrink_to_fit 函数用于将 vector 的容量缩减到当前大小,以节省内存。

template <typename T>
void Vector<T>::shrink_to_fit() {if (size < capacity) {// 创建一个临时数组,容量为当前大小T* new_data = new T[size];for (size_t i = 0; i < size; ++i) {new_data[i] = std::move(data[i]); // 移动元素到新数组}// 释放旧数组delete[] data;// 更新指针和容量data = new_data;capacity = size;}
}

注意:这个函数不常用。因为这个函数是请求把多余的内存还给系统,不一定会成功。

3.5.3 动态扩容(reserve)

reserve 函数用于确保 vector 的容量至少为指定值。如果当前容量不足,则扩容。

template <typename T>
void Vector<T>::reserve(size_t new_capacity) {if (new_capacity <= capacity) return; // 如果容量足够,直接返回// 创建新数组T* new_data = new T[new_capacity];for (size_t i = 0; i < size; ++i) {new_data[i] = std::move(data[i]); // 移动元素到新数组}// 释放旧数组delete[] data;// 更新指针和容量data = new_data;capacity = new_capacity;
}

说明:

  • 如果 new_capacity <= capacity,直接返回。如果当前数组容量大于新的数组容量,那么就会直接返回。
  • 否则,创建一个新数组,容量为 new_capacity。再使用 std::move 将元素从旧数组移动到新数组。释放旧数组,并更新 data和capacity

3.6 添加元素

3.6.1 添加左值元素

将元素拷贝到 vector 的头部。

template <typename T>
void Vector<T>::insert(const T& value) {if (size >= capacity) {reserve(capacity == 0 ? 4 : capacity * 2);}data[size++] = value;
}

3.6.2 添加右值元素

将元素拷贝到 vector 的末尾。

template <typename T>
void Vector<T>::push_back(const T& value) {if (size >= capacity) {reserve(capacity == 0 ? 1 : capacity * 2);}data[size++] = value;
}

3.7 删除元素

3.7.1 删除指定位置元素

删除指定位置元素。

iterator erase(iterator pos)
{assert(pos >= _start && pos < _finish);iterator i = pos + 1;while (i < _finish){*(i - 1) = *i;++i;}_finish--;return pos;
}

3.7.2 尾删

删除尾部位置的元素。

void pop_back()
{assert(!empty());--_finish;
}

注意:erase尽量少用。由于erase可以删除任意位置的元素,所以会涉及到大量的数组容量更改操作。这会大幅降低程序效率。

3.8 元素访问

3.8.1 通过下标访问元素

T& operator[](size_t i)
{assert(i < size());return _start[i];
}

3.9 迭代器支持

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

4. 总结

通过这个详细的实现,我们深入了解了 std::vector 的核心机制,包括动态扩容、拷贝/移动语义、迭代器支持等。

希望这篇博客对你有所帮助!如果有任何问题或建议,欢迎留言讨论。

5. 附录

5.1 测试用例

	void test_vector01(){vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);for (auto ch : v1){cout << ch << " ";}cout << endl;for (int i = 0; i < v1.size(); i++){cout << v1[i] << " ";}cout << endl;v1.pop_back();for (auto ch : v1){cout << ch << " ";}cout << endl;// pop_back只能尾删,v1.pop_back(1)行不通;int n = *v1.begin();cout << n << endl;vector<int>::iterator it1 = v1.begin();vector<int>::iterator it2 = v1.end();while (it1 != it2){cout << *it1++ << " ";}cout << endl;}void test_vector02(){vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);for (auto e : v1){cout << e << " ";}cout << endl;// 第一种使用迭代器在指定位置插入数字v1.insert(v1.begin() + 1, 26);for (auto e : v1){cout << e << " ";}cout << endl;}void test_vector03(){vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);vector<int>::iterator it1 = v1.begin();vector<int>::iterator it2 = v1.end();auto x = 0;cin >> x;// 第二种使用迭代器 在指定位置插入指定倍数的数字auto it = find(it1, it2, x);if (it != it2){it = v1.insert(it, 10 * x);cout << *it << endl;}for (auto e : v1){cout << e << " ";}cout << endl;}void test_vector04(){vector<int> v1;// 这一遍是模拟实现的// 这里必须使用系统自带的vector,不然程序会报错中止//std::vector<int> v1;// 这里就是编译器自带的v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);int x;cin >> x;auto it = find(v1.begin(), v1.end(), x);// 删除指定位置的数while (it != v1.end()){v1.erase(it);}for (auto e : v1){cout << e << " ";}cout << endl;}void test_vector05(){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(23);v1.push_back(42);v1.push_back(33);v1.push_back(533);v1.push_back(234);v1.push_back(23454);v1.push_back(534534534);for (auto e : v1){cout << e << " ";}cout << endl;// 要求删除所有的偶数auto it = v1.begin();while (it != v1.end()){if (*it % 2 == 0){// erase返回删除位置下一个位置// 失效的迭代器,更新以后再去访问v1.erase(it);}else {it++;}}for (auto e : v1){cout << e << " ";}cout << endl;}void test_vector06(){vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);for (auto e : v1){cout << e << " ";}cout << endl;// 将v1的size改为20,自动填充0v1.resize(20);for (auto e : v1){cout << e << " ";}cout << endl;// 也可以指定数字。只是已经填充进去的数字无法更改v1.resize(25, 1);for (auto e : v1){cout << e << " ";}cout << endl;v1.resize(2);for (auto e : v1){cout << e << " ";}cout << endl;}void test_vector07(){vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);for (auto e : v1){cout << e << " ";}cout << endl;vector<int> v2(v1);for (auto e : v2){cout << e << " ";}cout << endl;vector<int> v3{ 1,2,3,4,5 };v1 = v3;for (auto e : v3){cout << e << " ";}cout << endl; for (auto e : v1){cout << e << " ";}cout << endl;}void test_vector08(){vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);for (auto e : v1){cout << e << " ";}cout << endl;vector<int> v2(v1.begin(), v1.end());for (auto e : v2){cout << e << " ";}cout << endl;std::string s1("hello world");vector<int> v3(s1.begin(),s1.end());// 打印的是ASSIC码值for (auto e : v3){cout << e << " ";}cout << endl;// 行不通//vector<int> v4(10, 1);//vector<double> v5(10, 1.1);//for (auto e : v4)//{//	cout << e << " ";//}//cout << endl;///*for (auto e : v5)//{//	cout << e << " ";//}//cout << endl;*/}void test_vector09(){vector<string> v1;v1.push_back("1111111111111111");v1.push_back("1111111111111111");v1.push_back("1111111111111111");v1.push_back("1111111111111111");v1.push_back("1111111111111111");for (auto e : v1){cout << e << " ";}cout << endl;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/73780.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

拖拽实现+摇杆实现

拖拽实现 拖拽事件实现: 半透明渐变贴图在ios设备下&#xff0c;使用压缩会造成图片质量损失&#xff0c;所以可以将半透明渐变UI切片单独制作真彩色图集 拖拽事件组 IBeginDragHandler:检测到射线后&#xff0c;当拖拽动作开始时执行一次回调函数 IDragHandler:拖拽开始后&a…

xLua_001 Lua 文件加载

xLua下载 1、HelloWrold 代码 using System.Collections; using System.Collections.Generic; using UnityEngine; using XLua; // 引入XLua命名空间 public class Helloworld01 : MonoBehaviour {//声明LuaEnv对象 private LuaEnv luaenv;void Start(){//实例化LuaEnv对象…

【sql靶场】第18-22关-htpp头部注入保姆级教程

目录 【sql靶场】第18-22关-htpp头部注入保姆级教程 1.回顾知识 1.http头部 2.报错注入 2.第十八关 1.尝试 2.爆出数据库名 3.爆出表名 4.爆出字段 5.爆出账号密码 3.第十九关 4.第二十关 5.第二十一关 6.第二十二关 【sql靶场】第18-22关-htpp头部注入保姆级教程…

Python----计算机视觉处理(Opencv:形态学变换)

一、形态学变化 形态学变换&#xff08;Morphological Transformations&#xff09;是一种基于形状的图像处理技术&#xff0c;主要处理的对象为二值化图像。 形态学变换有两个输入和一个输出&#xff1a;输入为原始图像和核&#xff08;即结构化元素&#xff09;&#xff0c;输…

【最新版】智慧小区物业管理小程序源码+uniapp全开源

一.系统介绍 智慧小区物业管理小程序,包含小区物业缴费、房产管理、在线报修、业主活动报名、在线商城等功能。为物业量身打造的智慧小区运营管理系统,贴合物业工作场景,轻松提高物业费用收缴率,更有功能模块个性化组合,助力物业节约成本高效运营。 二.搭建环境 系统环…

C++模板进阶

目录 非类型模板参数 类模板的特化 分类 函数模板的特化 模板分离编译 问题 解决方法 1&#xff09;不对模板定义进行分离或对模板进行特例化&#xff1b; 2&#xff09;将声明和定义放在同一个文件 总结 关于C模板的使用在《C类和对象》中有介绍&#xff0c;本篇博客…

停车场停车位数据集,标注停车位上是否有车,平均正确识别率99.5%,支持yolov5-11, coco json,darknet,xml格式标注

停车场停车位数据集&#xff0c;标注停车位上是否有车&#xff0c;平均正确识别率98.0&#xff05;&#xff0c;支持yolov5-11&#xff0c; coco json&#xff0c;darknet&#xff0c;xml格式标注 数据集-识别停车场所有车辆的数据集 数据集分割 一共184张图片 训练组 89&am…

Lora微LLAMA模型实战

引言 本文介绍如何复现Alpaca-lora&#xff0c;即基于alpaca数据集用lora方法微调Llama模型。 环境准备 实验环境用的是lanyun&#xff0c;新用户点击注册可以送算力。 下载huggingface上的模型是一个令人头疼的问题&#xff0c;但在lanyun上可以通过在终端运行source /etc…

什么是站群服务器?站群服务器应该怎么选?

站群服务器是专门用于托管和管理多个网站的服务器。通常用于SEO优化、内容分发、广告推广等场景&#xff0c;用户可以通过一个服务器管理多个站点&#xff0c;提升效率并降低成本。选择站群服务器时&#xff0c;需根据业务需求、性能要求、IP资源等因素进行综合考虑。 什么是站…

【LInux进程六】命令行参数和环境变量

【LInux进程六】命令行参数和环境变量 1.main函数的两个参数2.利用main函数实现一个简单的计算器3.环境变量之一&#xff1a;PATH4.修改PATH5.在命令行解释器bash中查看所有环境变量6.用自己写的程序查看环境变量7.main函数的第三个参数8.本地的环境变量和环境变量9.环境变量具…

大语言模型的压缩技术

尽管人们对越来越大的语言模型一直很感兴趣&#xff0c;但MistralAI 向我们表明&#xff0c;规模只是相对而言的&#xff0c;而对边缘计算日益增长的兴趣促使我们使用小型语言获得不错的结果。压缩技术提供了一种替代方法。在本文中&#xff0c;我将解释这些技术&#xff0c;并…

大华HTTP协议在智联视频超融合平台中的接入方法

一. 大华HTTP协议介绍 大华HTTP协议是大华股份&#xff08;Dahua Technology&#xff09;为其安防监控设备开发的一套基于HTTP/HTTPS的通信协议&#xff0c;主要用于设备与客户端&#xff08;如PC、手机、服务器&#xff09;之间的数据交互。该协议支持设备管理、视频流获取、…

7、vue3做了什么

大佬认为有何优点&#xff1a; 组合式api----逻辑集中、对ts有更好的支持RFC–开放了一个讨论机制&#xff0c;可以看到每一个api的提案&#xff0c;方便源码维护&#xff0c;功能扩展&#xff0c;大家一起讨论 官方rfc响应式独立&#xff0c;new Proxy&#xff0c;天生自带来…

多人在线聊天系统,创建群,视频,语音,自带带授权码

多人在线聊天系统&#xff0c;创建群&#xff0c;视频&#xff0c;语音 带授权码&#xff0c;授权码限制 10 个网站&#xff0c;需要下载研究吧 在线聊天&#xff0c;创建群&#xff0c;表情&#xff0c;图片&#xff0c;文件&#xff0c;视频&#xff0c;语音&#xff0c;自…

NFC 碰一碰发视频源码搭建,支持OEM

一、引言 NFC&#xff08;Near Field Communication&#xff09;近场通信技术&#xff0c;以其便捷、快速的数据交互特性&#xff0c;正广泛应用于各个领域。其中&#xff0c;NFC 碰一碰发视频这一应用场景&#xff0c;为用户带来了新颖且高效的视频分享体验。想象一下&#x…

C++从入门到入土(八)——多态的原理

目录 前言 多态的原理 动态绑定与静态绑定 虚函数表 小结 前言 在前面的文章中&#xff0c;我们介绍了C三大特性之一的多态&#xff0c;我们主要介绍了多态的构成条件&#xff0c;但是对于多态的原理我们探讨的是不够深入的&#xff0c;下面这这一篇文章&#xff0c;我们将…

Linux目录理解

前言 最近在复习linux&#xff0c;发现有些目录总是忘记内容&#xff0c;发现有些还是得从原义和实际例子去理解会记忆深刻些。以下是个人的一些理解 Linux目录 常见的Linux下的目录如下&#xff1a; 1. 根目录 / (Root Directory) 英文含义&#xff1a;/ 是文件系统的根…

c++领域展开第十七幕——STL(vector容器的模拟实现以及迭代器失效问题)超详细!!!!

文章目录 前言vector——基本模型vector——迭代器模拟实现vector——容量函数以及push_back、pop_backvector——默认成员函数vector——运算符重载vector——插入和删除函数vector——实现过程的问题迭代器失效memcpy的浅拷贝问题 总结 前言 上篇博客我们已经详细介绍了vecto…

植物知识分享论坛毕设

1.这四个文件直接是什么关系&#xff1f;各自都是什么作用&#xff1f;他们之间是如何联系的&#xff1f; 关系与联系 UserController.java 负责接收外部请求&#xff0c;调用 UserService.java 里的方法来处理业务&#xff0c; 而 UserService.java 又会调用 UserMapper.jav…

Business processes A bridge to SAP and a guide to SAP TS410 certification

Business processes A bridge to SAP and a guide to SAP TS410 certification