2023/9/14 -- C++/QT

作业:

仿照Vector实现MyVector,最主要实现二倍扩容

#include <iostream>using namespace std;template <typename T>
class MyVector
{
private:T *data;size_t size;size_t V_capacity;
public://无参构造MyVector():data(nullptr),size(0),V_capacity(0) {//cout<<"MyVector::无参构造"<<endl;}//有参构造MyVector(int count,T val){size = count;V_capacity = count;data = new T[count];for(int i = 0;i < count;i++){data[i] = val;}//cout<<"MyVector::有参构造"<<endl;}//析构函数~MyVector(){delete [] data;data = nullptr;//cout<<"MyVector::析构函数"<<endl;}// 定义迭代器类class MyIterator {private:T* ptr;public://有参构造MyIterator(T* p):ptr(p){//cout<<"MyIterator::有参构造"<<endl;}// *重载T& operator*()const {return *ptr;}// 前置++重载MyIterator& operator++() {++ptr;return *this;}// 后置++重载MyIterator operator++(int) {MyIterator temp = *this;++ptr;return temp;}// 前置--重载MyIterator& operator--() {--ptr;return *this;}// 后置--重载MyIterator operator--(int) {MyIterator temp = *this;--ptr;return temp;}// ==重载bool operator==(const MyIterator& other) const {return ptr == other.ptr;}// !=重载bool operator!=(const MyIterator& other) const {return ptr != other.ptr;}};//begin 函数  返回第一个元素的迭代器MyIterator begin() {return MyIterator(data);}//end 函数  返回最末元素的迭代器(注:实指向最末元素的下一个位置)MyIterator end() {return MyIterator(data + size);}//assign 函数  对MyVector中的元素赋值void assign(size_t num, const T &val ){for(int i = 0;i < num;i++){data[i] = val;}cout<<"assign 函数"<<endl;}//at 函数  返回指定位置的元素T at(int pos){if(pos < 0 || pos >= size){throw int(1);                 //抛出异常}return data[pos];}//back 函数 返回最末一个元素T back(){return data[size-1];}//capacity 函数  返回vector所能容纳的元素数量size_t capacity(){return V_capacity;}//clear 函数  清空所有元素void clear(){size = 0;}//empty 函数  判空bool empty(){return size == 0;}//front 函数  返回第一个元素T front(){return data[0];}//pop_back 函数  移除最后一个元素void pop_back(){if(empty()){throw int(2);           //抛出异常}size--;}//push_back 函数  在MyVector最后添加一个元素void push_back(const T& value) {if (size == V_capacity) {// 扩容逻辑size_t newCapacity = (V_capacity == 0)?1:V_capacity * 2;T* newData = new T[newCapacity];for(int i = 0;i < static_cast<int>(size);i++){newData[i] = data[i];}delete[] data;data = newData;V_capacity = newCapacity;}data[size++] = value;}//size 函数  返回Vector元素数量的大小size_t get_size(){return size;}
};int main()
{MyVector<int> V1(5,2);cout<<"V1的第一个元素 = "<<V1.front()<<endl;cout<<"V1的最末一个元素 = "<<V1.back()<<endl;cout<<"V1的capacity = "<<V1.capacity()<<endl;cout<<endl;cout<<"********************************************************"<<endl;cout<<endl;V1.push_back(8);V1.push_back(5);V1.push_back(7);V1.push_back(6);cout<<"V1的第一个元素 = "<<V1.front()<<endl;cout<<"V1的最末一个元素 = "<<V1.back()<<endl;cout<<"V1的capacity = "<<V1.capacity()<<endl;cout<<"V1的size = "<<V1.get_size()<<endl;cout<<endl;cout<<"********************************************************"<<endl;cout<<endl;int *p = NULL;MyVector<int>::MyIterator q(p);cout<<"当前容器内的元素:";for(q = V1.begin();q != V1.end();q++){cout<< *q <<"\t";}cout<<endl;cout<<endl;cout<<"********************************************************"<<endl;cout<<endl;V1.pop_back();cout<<"V1的最末一个元素 = "<<V1.back()<<endl;V1.pop_back();cout<<"V1的最末一个元素 = "<<V1.back()<<endl;V1.pop_back();cout<<"V1的最末一个元素 = "<<V1.back()<<endl;cout<<"V1的size = "<<V1.get_size()<<endl;cout<<endl;cout<<"********************************************************"<<endl;cout<<endl;V1.clear();cout<<"V1的size = "<<V1.get_size()<<endl;return 0;
}

效果图:

一、异常处理

【1】异常概念

C++中的异常指的是在程序运行过程中出现的问题,没有任何语法错误,存在逻辑问题

【2】异常处理

  1. throw ----->抛出异常,抛出异常一定在异常发生之前
  2. try ····catch ----->捕获异常并进行异常处理

总结:

  1. 抛出异常一定在发生异常之前
  2. try···catch中可以存放所有可能发生异常的代码,只要有一条语句抛出异常,try后面的语句都不会执行
  3. 异常可以只有数据类型,也可以及有数据类型也有值
  4. catch可以通过数据类型,获取到异常的结果并使用if进行判断,如果每种异常抛出的都是不同的数据类型,catch中就无需定义变量
  5. 如果同种数据类型的异常有多个值,要依次根据值来判断异常的情况
  6. throw抛出异常往往被调函数的位置,try···catch往往在主调函数内处理异常
#include <iostream>
using namespace std;void fun(int a,int b)
{//throw 数据类型(值)//数据类型:指定抛出异常的类型,便于接收//值:针对不同的异常情况,给出不同的值,处理异常时使用//在执行语句之前先对可能发生异常的位置进行判断if(b==0){throw double(1);}if(b==3){//函数内抛出了两个double类型的异常,分别返回不同的值throw int(2);}if(b==2){throw double(2);}cout << a/b << endl;
}//处理异常一般在主函数内
//try···catch处理异常
int main()
{//tyr尝试接收异常,try内可以放多条语句,//有一条语句抛出异常后,后面都不会执行try{//try去接收所有可能的异常fun(4,2);fun(2,1);fun(3,3);}//由于函数中,只有一个double类型的异常,所以可以直接对异常的类型进行判断catch (double a)    //如果double后面加变量名,变量会获取到异常的结果{if(a==1)cout << "除数为0" << endl;if(a==2)cout << "除数为2是一个测试" << endl;}catch (int){cout << "除数为3是一个测试" << endl;}fun(3,1);cout << "1" << endl;
}

二、using的第三种用法

#include <iostream>//using namespace std;
using std::string;
class A
{
public:string name;
};
class B:public A
{
protected:using A::name;
};
namespace P {string n1;
}//给命名空间重命名
//namespace 新的名字 = 旧的名字
//新名字和旧名字都能用
namespace O = P;
int main()
{using std::cout;using std::endl;typedef int a;    //后面可以直接使用a定义int类型的变量//C++11支持的using  INT  = int;   //后面可以直接使用INT定义int类型的变量INT num1 = 100;cout << num1 << endl;P::n1 = "helo";O::n1 = "hi";cout << O::n1 << endl;return 0;
}

三、类型转换

【1】隐式强转

以及和C中一致的显式强转

#include <iostream>
using namespace std;int main()
{float num1 = 2.3;int num2 = num1;    //发生了隐式的强制类型转换//C中的显式强制类型转换double num3 = (double)num2;cout << num2 << endl;return 0;
}

【2】C++中支持的强制类型转换

  1. const_cast,取消常属性,取消常量指针的属性
  2. static_cast,和平时使用时发生强转用法一致,几乎支持所有类型间的强转
  3. dynamic_cast,发生在父子类指针间的转换,如果转换失败,会返回空地址
  4. reinterpret_cast,给类型重新赋值,不常用,不会检查数据类型匹配问题
#include <iostream>
using namespace std;class A
{string name;
public:virtual void show(){cout << name << endl;}
};class B:public A
{mutable int age;
public:void fun()const{age = 90;}void show(){cout << &age << endl;}    
};int main()
{//定义了一个常量num1const int num1 = 90;int *p;   //定义了一个指针变量p = const_cast<int *>(&num1);   //使用const_cast让指针指向const修饰的变量的地址*p = 12;cout << *p << endl;//mutable关键也可以取消常属性//static_cast适用于几乎所有的强制类型转换char var = 'a';int num2;//int num2 = (int)var;num2 = static_cast<int>(var);cout << num2 << endl;A* p1 = new B;    //父类指针指向子类的空间A* p2 = new A;    //父类指针指向父类的空间//B* p3 = static_cast<B*>(p2);  p2指向父类的空间,但是static_cast可以强转成功B* p3 = dynamic_cast<B*>(p2);//使用了dynamic_cast,可以实现多态情况下,可以实现父子类指针的转换//如果父类指针没有指向子类的空间,返回值为0cout << "父类指针指向父类的空间" << p2 << endl;cout << "子类的指针" << p3 << endl;B* p4 = reinterpret_cast<B*>(p2);cout << "父类指针指向父类的空间" << p2 << endl;cout << "子类的指针" << p4 << endl;char *str = "hello";int a = reinterpret_cast<int>(str);cout << a << endl;//p3->show();return 0;
}

四、lambda表达式

应用场合:

想要使用匿名的、临时的函数,并且还需要获取外部变量时

  1. lambda(λ)表达式,是C++11支持的
  2. lambda表达式,用于实现轻量级的匿名函数
  3. 定义:[]()mutable->返回值{函数体}; --->结果一般使用auto接收
[捕获列表](参数列表)mutable->返回值{函数体};
1、[=]:对所有变量按值捕获[&]:对所有变量按引用捕获[a,b]:对a和b按值捕获[&a,&b]:对a和b按引用捕获//[=,&a]:对除a外的变量值捕获,a按引用捕获//[&,a]:对除a外的变量按引用捕获,a按值捕获2、参数列表:和普通函数的参数一致,就是传参数到函数中
3、mutable可以写也可以不写:
如果不写mutable,在lambda表达式中不能修改按值捕获的变量的值,按引用捕获的不受影响
4、lambda实现的匿名函数的返回值
5、函数体就是匿名函数的实现
#include <iostream>
using namespace std;int main()
{int a = 90,b = 7,c,d,e;cout << "a=" << a << endl;cout << "b=" << b << endl;cout << "--------------------" << endl;//使用lambda表达式,实现主函数内变量值的交换//[=]:对所有变量按值捕获//[&]:对所有变量按引用捕获//[a,b]:对a和b按值捕获//[&a,&b]:对a和b按引用捕获//[=,&a]:对除a外的变量值捕获,a按引用捕获//[&,a]:对除a外的变量按引用捕获,a按值捕获//lambda表示式,使用auto类型获取auto fun = [&,a]()mutable->void{ int temp;temp = a;a = b;b = temp;};fun();//使用lambda实现求最大值auto max = [=]()->int{  if(a>b)return a;elsereturn b; };cout << max() << endl;return 0;
}

五、STL标准模板库

C++ Standard Template Library

C++ 标准模板库(STL)

C++ STL (Standard Template Library标准模板库) 是通用类模板和算法的集合,它提供给程序员一些标准的数据结构的实现如 queues(队列), lists(链表), 和 stacks(栈)等.

C++ STL 提供给程序员以下三类数据结构的实现:

  • 顺序结构
    • C++ Vectors
    • C++ Lists
    • C++ Double-Ended Queues
  • 容器适配器
    • C++ Stacks
    • C++ Queues
    • C++ Priority Queues
  • 联合容器
    • C++ Bitsets
    • C++ Maps
    • C++ Multimaps
    • C++ Sets
    • C++ Multisets

【1】Vector

Vector的底层实现,就是线性表

Vectors 包含着一系列连续存储的元素,其行为和数组类似。访问Vector中的任意元素或从末尾添加元素都可以在常量级时间复杂度内完成,而查找特定值的元素所处的位置或是在Vector中插入元素则是线性时间复杂度。

需要手动导入头文件#include

1、求vetcor容器的大小:
size_type capacity();
capacity() 函数 返回当前vector在重新进行内存分配以前所能容纳的元素数量.
2、添加元素
void push_back( const TYPE &val );
push_back()添加值为val的元素到当前vector末尾
3、求容器的真实大小
size_type size();
size() 函数返回当前vector所容纳元素的数目 
4、给容器中的元素赋值
void assign( size_type num, const TYPE &val );
赋num个值为val的元素到vector中.这个函数将会清除掉为vector赋值以前的内容.
5、访问容器中的元素
TYPE at( size_type loc );
at() 函数 返回当前Vector指定位置loc的元素的引用. at() 函数 比 [] 运算符更加安全, 因为它不会让你去访问到Vector内越界的元素.
6、清空容器中的元素
void clear();
clear()函数删除当前vector中的所有元素.
7、判空函数
bool empty();
如果当前vector没有容纳任何元素,则empty()函数返回true,否则返回false.例如,以下代码清空一个vector,并按照逆序显示所有的元素:
8、返回起始位置的引用
TYPE front();
front()函数返回当前vector起始元素的引用
9、返回最后一个位置的引用
TYPE back();
back() 函数返回当前vector最末一个元素的引用.    
10、返回起始元素的迭代器
iterator begin();
begin()函数返回一个指向当前vector起始元素的迭代器.
11、返回末尾下一个位置的迭代器
iterator end();
end() 函数返回一个指向当前vector末尾元素的下一位置的迭代器.
注意,如果你要访问末尾元素,需要先将此迭代器自减1.
12、指定位置的插入,由于没有提供返回指定位置迭代器,需要在第一个元素的迭代器上运算
iterator insert( iterator loc, const TYPE &val );
在指定位置loc前插入值为val的元素,返回指向这个元素的迭代器, 
13、移除最后一个元素
void pop_back();
pop_back()函数删除当前vector最末的一个元素,
14、构造函数
vector( input_iterator start, input_iterator end );
迭代器(start)和迭代器(end) - 构造一个初始值为[start,end)区间元素的Vector(注:半开区间). 

【2】List

list的底层实现是一个双向链表

主要功能

1、头插
void push_front( const TYPE &val );
push_front()函数将val连接到链表的头部。
2、最大容量
size_type max_size();
max_size()函数返回链表能够储存的元素数目
3、元素个数
size_type size();
size()函数返回list中元素的数量。
4、排序
void sort();
给链表中的元素排序,默认是升序
5、判空
bool empty();
empty()函数返回真(true)如果链表为空,否则返回假。

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

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

相关文章

【深度学习 AIGC】stablediffusion-infinity 在无界限画布中输出绘画 Outpainting

代码&#xff1a;https://github.com/lkwq007/stablediffusion-infinity/tree/master 启动环境&#xff1a; git clone --recurse-submodules https://github.com/lkwq007/stablediffusion-infinity cd stablediffusion-infinity conda env create -f environment.yml conda …

如何开启Win10虚拟机Hyper-V功能

操作步骤: 使用前提&#xff1a; 1、确保系统是 Windows 10 专业版/企业版/教育版&#xff0c;且必须是64位操作系统才支持。 提示&#xff1a;Win10家庭版不支持hyper-v。 2、使用Hyper-V需要cpu支持虚拟化并处于开启状态。 3、硬件要求及如何验证硬件兼容性&#xff1a; 硬件…

什么是云存储,从对象存储说起?

在《存储系统形态之争,从块存储到统一存储》一文中我们提到了对象存储的概念,知道目前很多企业级存储都是支持对象存储的,比如EMC、NetApp和华为等。以EMC的对象存储为例,其最早在1998年就已经具备成熟的产品了,到目前已经有二十多年的历史了。如图是关于对象存储主要产品…

SpringMVC之JSR303和拦截器

一.什么是JSR303 二.JSR303 常用注解 作用 使用 导入pom.xml 在实体类相对应的属性中增加注解用来指定校验 在hpjyController里面新加以下代码 修改eidt.jsp 测试结果 ​编辑 二.拦截器 什么是拦截器 拦截器与过滤器的区别 应用场景日志记录&#xff1a;拦截器可以用…

图解第一类曲线积分与第二类曲线积分的关系

图解第一类曲线积分与第二类曲线积分的关系 笔记相关内容&#xff1a; 1.曲线积分&#xff08;Line Integral&#xff09; 2.向量场中的曲线积分、环量、通量 第一类曲线积分&#xff08;对弧长 d s ds ds进行积分&#xff09;(无方向性) 物理意义&#xff1a; f ( x , y ) f(…

Docker 一键安装Confluence(已支持最新版本)

Docker 一键安装Confluence&#xff08;已支持最新版本&#xff09; 本文用于Confluence在Docker的安装&#xff0c;仅用于记录安装方式Jira 也可以参考这种方式安装&#xff0c;只有细微差别转载请注明来源Linux安装可参考链接Windows安装可查考链接条件允许时&#xff0c;请…

java编辑pdf(itextpdf)

工作上遇到一个小需求&#xff0c;需要在原有的pdf文件上添加一行文字&#xff0c;实现方式如下 引入依赖 <dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.13</version></dependen…

【千万别上当】揭秘又一个割韭菜的项目:明星网红直播切片项目

今天在某乎浏览内容&#xff0c;看到一篇文章《我做了10个某音号&#xff0c;不拍视频&#xff0c;不直播&#xff0c;光靠剪辑明星素材月入8K&#xff0c;给缺钱的朋友推荐一个无脑赚Q的自媒体项目》&#xff0c;点击进去一看&#xff0c;洋洋洒洒估计有一两万字&#xff0c;过…

【SA8295P 源码分析】97 - QNX AIS Camera 框架介绍 及 Camera 工作流程分析

【SA8295P 源码分析】97 - QNX AIS Camera 框架介绍 及 Camera 工作流程分析 一、QNX AIS Server 框架分析二、QNX Hypervisor / Android GVM 方案介绍三、Camera APP 调用流程分析四、QCarCam 状态转换过程介绍五、Camera 加串-解串 硬件链路分析六、摄像头初始化检测过程介绍…

原生js vue react通用的递归函数

1.递归函数的由来 递归函数的由来可以追溯到数学中的递归概念和数学归纳法。 在数学中&#xff0c;递归是指通过定义基本情况和递推公式&#xff0c;将一个问题分解为更简单的、与原问题具有相同结构的子问题&#xff0c;并用子问题的解来构建原问题的解。递归的思想在解决一些…

【JavaScript】在指定dom元素前面创建标签元素

一、基础操作过程 要在指定的DOM元素前面创建标签元素&#xff0c;有以下步骤&#xff1a; 获取指定的DOM元素&#xff1a;使用document.querySelector()或document.getElementById()等方法来获取指定的DOM元素。 const targetElement document.querySelector(#targetElement…

NOA高歌猛进,智驾地图何去何从?

作者|德新 编辑|王博 今年是辅助驾驶的量产大年&#xff0c;尤其高阶智能驾驶&#xff0c;带动了上游需求的爆发。 一些典型的科技赛道&#xff0c;如激光雷达、大算力芯片等环节都从中受益。禾赛科技、地平线近期都公布了产品出货达到新的里程碑。禾赛AT系列产品上半年的出货…

亲测好用-obsidian无法打开插件库安装或更新的解决办法-结合FastGithub

写在前面 经过半年左右时间的使用情况验证该方案稳定可靠。 方案&#xff1a;插件“Plugin Proxy” 软件“FastGithub” 效果&#xff1a; 插件“Plugin Proxy” 下载地址&#xff1a; https://github.com/gslnzfq/obsidian-proxy-server 插件安装&#xff1a; 插件设置为…

多态的笔记

什么是多态 顾名思义多态就是让一个对象拥有不同的形态 举例如下 多态的应用场景&#xff0c;比如你注册的时候&#xff0c;你可能注册为学生&#xff0c;老师&#xff0c;管理员&#xff0c;但是此时你往函数传递的类型是什么呢&#xff0c;此时你无论传递什么都不太合适&am…

Marin说PCB之封装设计系列---(02)--异形焊盘的封装设计总结

每天下班回家看电视本来是一件很美好的事情&#xff0c;可是正当我磕着瓜子看着异人之下的时候&#xff0c;手机突然响起来了&#xff0c;我以为是我们组哪个同事找我呢。一接电话居然是我的老朋友陈世美陈总&#xff0c;江湖人称少妇杀手。给我打电话主要是说他最近遇到一个异…

回归预测 | MATLAB实现PSO-SDAE粒子群优化堆叠去噪自编码器多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现PSO-SDAE粒子群优化堆叠去噪自编码器多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现PSO-SDAE粒子群优化堆叠去噪自编码器多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09;效果一览…

【建议收藏】自动化测试框架开发教程

在自动化测试项目中&#xff0c;为了实现更多功能&#xff0c;我们需要引入不同的库、框架。 首先&#xff0c;你需要将常用的这些库、框架都装上。 pip install requests pip install selenium pip install appium pip install pytest pip install pytest-rerunfailures pip …

华为GaussDB数据库

Gauss数据库初识_高斯数据库_ygpGoogle的博客-CSDN博客 Redhat 7.6安装GaussDB_100_1.0.1详细攻略_gaussdb_100_1.0.1-database-redhat-64bit.tar.gz dow_博德1999的博客-CSDN博客 https://www.ngui.cc/el/3381579.html?actiononClick 初识GaussDB——GaussDB的发展历程、部…

学习Bootstrap 5的第六天

目录 信息警告框 警告框 实例 警告框链接 实例 关闭警告框 实例 警告框动画 实例 按钮 按钮样式 实例 按钮轮廓 实例 ​编辑按钮尺寸 实例 块级按钮 实例 实例 活动/禁用按钮 实例 加载器按钮 实例 扩展小知识 按钮组 按钮组 实例 实例 垂直按钮组…

python自(2)切片 字典 遍历删除添加修改查询定义函数函数返回值作用域序列化异常报错urllib使用一个类型六个方法下载 视频音频图片

切片 # # 切片# s hello word# # 下标索引为0的 # print(s[0]) #h# # 左闭右开 &#xff08;左是下标开始的&#xff0c;右是几个索引值&#xff09;例如从0开始算 4个索引值 # print(s[0:4]) #hell# # 更改起始值的开始位置 # print(s[1:]) #ello word# # 下标结束位置 # p…