C++初阶:vector类的模拟实现(含模板)

 

目录

1.Vector.h

2.Test.cpp


1.Vector.h

#include <iostream>
#include <cassert>
#include <algorithm>
using namespace std;
template <class T>
class Vector
{
public:typedef T *iterator;typedef const T *const_iterator;iterator begin() const{return _start;}iterator end() const{return _finish;}size_t size() const{return _finish - _start;}size_t capacity() const{return _endofstorage - _start;}T &operator[](size_t i){assert(i < size());return _start[i];}const T &operator[](size_t pos) const{assert(pos < size());return _start[pos];}Vector<T> &operator=(Vector<T> v){swap(v);return *this;}Vector() {}Vector(const Vector<T> &v){reserve(v.capacity());for (auto &e : v){push_back(e);}}Vector(initializer_list<T> il){reserve(il.size());for (auto &e : il){push_back(e);}}template <class InputIterator>Vector(InputIterator first, InputIterator last){while (first != last){push_back(*first);++first;}}// 防止push整型时失效Vector(int n, const T &val = T()){reserve(n);for (int i = 0; i < n; i++){push_back(val);}}Vector(size_t n, const T &val = T()){reserve(n);for (size_t i = 0; i < n; i++){push_back(val);}}~Vector(){if (_start){delete[] _start;_start = _finish = _endofstorage = nullptr;}}void reserve(size_t n){if (n > capacity()){T *temp = new T[n];size_t _size = size();for (size_t i = 0; i < _size; ++i){temp[i] = _start[i];}delete[] _start;_start = temp;_finish = _start + _size;_endofstorage = _start + n;}}void resize(size_t n, T val = T()){if (n > size()){reserve(n);while (_finish != _endofstorage){*_finish = val;_finish++;}}else{// 忽视后面的元素,直接修改_finish的指向_finish = _start + n;}}void push_back(const T &value){if (_finish == _endofstorage){reserve(capacity() == 0 ? 4 : capacity() * 2);}*_finish = value;++_finish;}void pop_back(){assert(!empty());--_finish;}// 检查容器是否为空bool empty(){return _start == _finish;}// 清理容器void clear(){// 让起点与终点重合_start = _finish = _endofstorage = nullptr;}iterator insert(iterator position, const T &val){// 检查插入位置是否在范围之中assert(position <= _finish && position >= _start);// 如果_finish==_endofstorage,那么需要对容器进行扩容if (_finish == _endofstorage){// 储存扩容前的相对位置size_t len = position - _start;reserve(capacity() == 0 ? 4 : capacity() * 2);// 扩容了需要对position进行更新position = _start + len;}iterator it = _finish - 1;while (it >= position){*(it + 1) = *it;it--;}*position = val;_finish++;return position;}iterator erase(iterator position){// 清除的部位必须在范围之内assert(position < _finish && position >= _start);iterator it = position + 1;while (it <= _finish){*(it - 1) = *it;it++;}_finish--;return position;}void swap(Vector<T> &temp){std::swap(_start, temp._start);std::swap(_finish, temp._finish);std::swap(_endofstorage, temp._endofstorage);}private:iterator _start = nullptr;iterator _finish = nullptr;iterator _endofstorage = nullptr;
};template <class T>
void print_Vector(const Vector<T> &v)
{for (size_t i = 0; i < v.size(); i++){cout << v[i] << " ";}cout << endl;
}

2.Test.cpp

#include "Vector.h"
void test_Vector1()
{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);print_Vector(v1);Vector<double> v2;v2.push_back(1.1);v2.push_back(2.2);v2.push_back(3.1);print_Vector(v2);v2.insert(v2.begin(), 11.11);print_Vector(v2);v2.insert(v2.begin(), 11.11);print_Vector(v2);v2.insert(v2.begin(), 11.11);print_Vector(v2);v2.insert(v2.begin(), 11.11);print_Vector(v2);v2.insert(v2.begin(), 11.11);print_Vector(v2);v2.erase(v2.begin());print_Vector(v2);v2.erase(v2.begin() + 4);print_Vector(v2);}void test_Vector2()
{// C++在引入了模板之后对于内置类型也进行了升级,对于int而言,其默认构造函数的初始化结果是0// int i = 1;// int j = int();// int k = int(2);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);print_Vector(v1);v1.resize(10);print_Vector(v1);v1.resize(3);print_Vector(v1);
}void test_Vector3()
{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);print_Vector(v1);v1.pop_back();Vector<int> v2(v1);print_Vector(v2);Vector<int> v3;v3.push_back(10);v3.push_back(20);v3.push_back(30);v1 = v3;print_Vector(v1);print_Vector(v3);
}void test_Vector4()
{Vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);print_Vector(v1);Vector<int> v2(v1.begin() + 1, v1.end() - 1);print_Vector(v2);string str("abcd");Vector<int> v3(str.begin(), str.end());print_Vector(v3);
}void test_Vector5()
{Vector<int> v1(10, 1);print_Vector(v1);Vector<int> v2(10, 1);print_Vector(v2);Vector<char> v3(10, 'a');print_Vector(v3);
}void test_Vector6()
{auto x = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};cout << typeid(x).name() << endl;cout << sizeof(x) << endl;initializer_list<int> y = {1, 2, 3, 4, 5, 6, 7};// 单参数的构造函数,隐式类型转换string str = "11111";         // 构造 + 拷贝构造 -> 优化 直接构造const string &str1 = "11111"; // 构造临时对象,引用的是临时对象Vector<string> v;v.push_back(str);v.push_back(string("22222"));v.push_back("33333");int i = 1;// 不推荐 -- C++11// int j = { 1 };int k{ 1 };// 跟上面类似// 隐式类型转换+优化// Vector<int> v1 = { 1,2,3,4,5,6,7,8,9,10 };Vector<int> v1{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};for (auto e : v1){cout << e << " ";}cout << endl;// 直接构造Vector<int> v2({10, 20, 30, 40});for (auto e : v2){cout << e << " ";}cout << endl;
}void test_Vector7()
{Vector<string> v;v.push_back("11111");v.push_back("22222");v.push_back("33333");v.push_back("44444");v.push_back("55555");for (auto &e : v){cout << e << " ";}cout << endl;
}void test_Vector8()
{Vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);v1.push_back(5);v1.push_back(6);v1.push_back(7);v1.push_back(8);print_Vector(v1);// insert以后,it就失效了,不要使用了Vector<int>::iterator it = v1.begin() + 3;v1.insert(it, 40);print_Vector(v1);it = v1.begin() + 3;cout << *it << endl;
}void test_Vector9()
{// std::Vector<int> v1;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(5);// v1.push_back(4);// 删除偶数 -- 迭代器失效以后,不要直接使用,如果要使用按规则重新更新后使用// std::Vector<int>::iterator it = v1.begin();Vector<int>::iterator it = v1.begin();// cout << typeid(it).name() << endl;while (it != v1.end()){if (*it % 2 == 0){it = v1.erase(it);}else{++it;}}for (auto e : v1){cout << e << " ";}cout << endl;
}int main()
{// test_Vector1();// test_Vector2();// test_Vector3();// test_Vector4();// test_Vector5();// test_Vector6();// test_Vector7();// test_Vector8();test_Vector9();return 0;
}

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

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

相关文章

8.list容器的使用

文章目录 list容器1.构造函数代码工程运行结果 2.赋值和交换代码工程运行结果 3.大小操作代码工程运行结果 4.插入和删除代码工程运行结果 5.数据存取工程代码运行结果 6.反转和排序代码工程运行结果 list容器 1.构造函数 /*1.默认构造-无参构造*/ /*2.通过区间的方式进行构造…

java-网络编程socket-聊天室-03

完整版代码 java -聊天室的代码: 用于存放聊天室的项目的代码和思路导图https://gitee.com/to-uphold-justice-for-others/java---code-for-chat-rooms.git 多线程并发问题 多线程的并发问题主要出现在当一个程序涉及多个线程同时运行时&#xff0c;这些线程可能会同时访问共…

conda删除环境指令

要删除Conda环境&#xff0c;你可以使用下面的指令&#xff1a; conda remove --name your_env_name --all这里的 your_env_name 是你想要删除的环境名称。这条指令会删除指定的环境及其下的所有包。 如果你正在使用的是Anaconda Prompt或者是命令行界面&#xff0c;确保你有…

Java:接口应用(Clonable 接口和深拷贝)

目录 1.引例2.Object中clone方法的实现3.Cloneable接口讲解4.深拷贝和浅拷贝4.1浅拷贝4.2深拷贝 1.引例 Java 中内置了一些很有用的接口, Clonable 就是其中之一. Object 类中存在一个 clone 方法, 调用这个方法可以创建一个对象的 “拷贝”. 但是要想合法调用 clone 方法。必…

精密电阻阻值表和电容容值表

前面2张是电阻阻值表&#xff08;E-96/0603/1%&#xff09; 常见贴片电容的容值表

解决windows下Qt Creator显示界面过大的问题

&#x1f40c;博主主页&#xff1a;&#x1f40c;​倔强的大蜗牛&#x1f40c;​ &#x1f4da;专栏分类&#xff1a;QT❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 问题描述 解决方法 1、右击此电脑--->属性 2、点击高级系统设置--->点击环境变量 3、 找到系…

【美团笔试题汇总】2023-08-26-美团春秋招笔试题-三语言题解(CPP/Python/Java)

&#x1f36d; 大家好这里是KK爱Coding &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新小米近期的春秋招笔试题汇总&#xff5e; &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f…

想要安装ssh?

SSH&#xff08;Secure Shell&#xff09;是一种加密的网络协议&#xff0c;用于在不安全的网络上安全地进行远程登录和执行命令。它通过加密通信和身份验证机制&#xff0c;确保用户和系统之间的通信是安全的。 SSH协议的主要功能包括&#xff1a; 加密通信&#xff1a;SSH使…

虚良SEO-蜘蛛池的作用与工作原理

蜘蛛池是一种SEO优化工具&#xff0c;其主要作用是吸引搜索引擎蜘蛛到特定网站进行爬行和索引&#xff0c;从而提高网站的可见性和排名。下面分别介绍蜘蛛池的作用和工作原理。 蜘蛛池的作用&#xff1a; 提高网站收录&#xff1a; 当一个网站新发布时&#xff0c;或者长时间…

哈佛大学商业评论 --- 第三篇:真实世界中的增强现实

AR将全面融入公司发展战略&#xff01; AR将成为人类和机器之间的新接口&#xff01; AR将成为人类的关键技术之一&#xff01; 请将此文转发给您的老板&#xff01; --- 本文作者&#xff1a;Michael E.Porter和James E.Heppelmann 虽然物理世界是三维的&#xff0c;但大…

如何查询大数据信用报告?查询时需要注意的事项有哪些?

在数字化时代&#xff0c;大数据信用评分对于需要资金周转的个人或企业来说至关重要。许多机构在贷款审批过程中使用大数据信用评分作为风险控制的重要手段。因此&#xff0c;了解自己的大数据信用状况成为了常规操作。本文将详细介绍如何查询大数据信用报告以及查询时需要注意…

ES6: class类

类 class 面相对象class关键字创建类关于类的继承 面相对象 一切皆对象。 举例&#xff1a; 操作浏览器要使用window对象&#xff1b;操作网页要使用document对象&#xff1b;操作控制台要使用console对象&#xff1b; ES6中增加了类的概念&#xff0c;其实ES5中已经可以实现类…

什么是 内网穿透

内网穿透是一种技术手段&#xff0c;用于在内部网络&#xff08;如家庭网络或公司网络&#xff09;中的设备能够被外部网络访问和控制。它允许将位于私有网络中的设备暴露在公共网络&#xff08;如互联网&#xff09;上&#xff0c;从而实现远程访问和管理。 内网穿透通常通过…

【云计算】云网络是未来的网络基础设施

云网络是未来的网络基础设施 1.什么是云网络2.云网络具备云的特征2.1 资源共享2.2 弹性伸缩2.3 自助服务2.4 可计量2.5 连接无处不在2.6 兼容性 3.云网络改变商业模式4.DevOps 变革产业生态 1.什么是云网络 到底什么是云网络&#xff1f;它和传统的网络有什么不同&#xff1f;…

震惊!子元素的padding/margin-top依据的是父元素的宽度!

子元素的margin-top和padding-top都是以父元素的宽度为基准 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" />…

7.java openCV4.x 入门-Mat之转换、重塑与计算

专栏简介 &#x1f492;个人主页 &#x1f4f0;专栏目录 点击上方查看更多内容 &#x1f4d6;心灵鸡汤&#x1f4d6;我们唯一拥有的就是今天&#xff0c;唯一能把握的也是今天建议把本文当作笔记来看&#xff0c;据说专栏目录里面有相应视频&#x1f92b; &#x1f9ed;文…

Mybatis 传参方式

1、mybatis简介 Mybatis 是⼀个半 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;它内部封装了 JDBC&#xff0c;开发时只需要关注 SQL 语句本身&#xff0c;不 需要花费精⼒去处理加载驱动、创建连接、创建statement 等繁杂的过程。程序员直接编写原⽣态 sql&#…

openEuler 22.03 SP3 安装图像桌面 UKUI

UKUI 是麒麟软件团队历经多年打造的一款 Linux 桌面&#xff0c;主要基于 GTK 和 QT 开发。与其他 UI 界面相比&#xff0c;UKUI 更加注重易用性和敏捷度&#xff0c;各元件相依性小&#xff0c;可以不依赖其他套件而独自运行&#xff0c;给用户带来亲切和高效的使用体验。 UK…

day2 | 数组 part-2 | 977 有序数组的平方、209 长度最小的子数组、59 螺旋矩阵 II

今日任务 977 有序数组的平方 (题目: . - 力扣&#xff08;LeetCode&#xff09;)209 长度最小的子数组 (题目: ​​​​​​​. - 力扣&#xff08;LeetCode&#xff09;)59 螺旋矩阵 II (题目:. - 力扣&#xff08;LeetCode&#xff09;) 有序数组的平方 (双指针) 给你一个…

如何使用 Viggle AI 生成模特动作视频

Viggle AI 是一款基于骨骼动画的 AI 工具&#xff0c;可以将图片转换为流畅且一致的角色动画。 这意味着您可以上传一张模特全身照&#xff0c;然后指定该模特要执行的动作&#xff0c;Viggle AI 会自动生成一段由该模特执行该动作的视频。 步骤 1&#xff1a;准备工作 首先&…