当前位置: 首页 > news >正文

迭代器(c++)、智能指针

一、迭代器

迭代器iterator是指针pointer的泛化,他允许程序员以相同的方式处理不同的数据结构(容器),提供了类似指针的操作(例如++、*、->运算符)或者说迭代器是一种检查容器的工具

不同容器的迭代器,其功能强弱有所不同,定义的操作不一样。常见的迭代器按功能强弱分为输入、输出、正向、双向、随机访问5中类型。

注意:所有的迭代器都支持++运算符,比如P++或++P

1、输入迭代器

Input lterator能单步向前迭代元素,不允许修改由该类迭代器引用的元素。输入迭代器用于从一个对象中不断读出元素。支持++与*操作符

格式:istream iterator<要从流中读取的数据类型>迭代器名(绑定的流);//创建的时候,就会调用标准输入

2、输出迭代器

Output lteratqr:该类迭代器和Input lterator极其相似,也只能单步向前迭代元素,不同的是该类迭代器对元素只有写的权力。向对象不断添加元素。ostream _iterator<要从流中读取的数据类型>迭代器名(绑定的流,元素分隔符);

3、正向迭代器

假设 p是一个正向迭代器,则p支持以下操作:++p,p++,*p。此外,两个正向迭代器可以互相赋值,还可以用==和!=运算符进行比较

4、双向迭代器

双向迭代器具有正向迭代器的全部功能。除此之外,若p是一个双向迭代器,则一p和p一都是有定义的。-p使得p朝和++p相反的方向移动。

5、随机访问迭代器

也是双向迭代器,但能够在序列中的任意两个位置之间进行跳转,如指针、使用vector的begin()、end()函数得到的迭代器

 实现一个超市购物系统

#include <iostream>
#include <string>
#include<iomanip>#include<vector>
#include<list>
#include<map>
#include<algorithm>
#include<array>using namespace std;
/*
1)利用今天学习的容器知识,用C++实现一个 模拟超市的购物流程提示:先存钱到变量拿一个购物篮构建一个超市进入购物(循环)结算环节打印小票用面向过程和面向对象编程思想分别实现分析:定义一个钱包 wallet定义一个数据结构来描述超市 {商品名称,价格} map vector描述购物过程:while(1){}   购物篮:品名,单价,数量结算:遍历购物篮 打印小票并汇总价格
*/float wallet=0;
float total=0.0f;//抽象超市
map<string,float>market={{"香肠",3.5},{"鸡蛋",2},{"芙蓉王",25},{"洗衣机",200},{"方便面",5}	
};//购物车
struct bar
{float price;int num;};map<string,struct bar> shoppingCar;int main()
{string goods_name;int goods_num;shoppingCar.clear();cout<<"请发钱";cin>>wallet;cout<<"==商品名称=========单价========"<<endl;for(auto e:market){cout<<e.first<<":"<<e.second<<endl;}while(1){cout<<"请输入你要购买的商品名称:";cin>>goods_name;cout<<endl;if(goods_name=="exit") break;cout<<"请输入你要购买的商品数量:";cin>>goods_num;if(market.find(goods_name)!=market.end()){if(shoppingCar.find(goods_name)==shoppingCar.end()){struct bar temp;temp.price=market[goods_name];temp.num=goods_num;shoppingCar[goods_name]=temp;}else{shoppingCar[goods_name].num=shoppingCar[goods_name].num+goods_num;}}else{cout<<"查无此商品"<<endl;}for(auto e:shoppingCar){cout<<"{"<<e.first<<":["<<e.second.num<<","<<e.second.price<<"]} ";}cout<<endl;}cout<<"========老郭家超市=========="<<endl;cout<<"商品名称\t商品单价\t商品数量\t"<<endl;for(auto e:shoppingCar){cout<<e.first<<"\t"<<e.second.price<<"\t"<<e.second.num<<endl;total=total+e.second.num*e.second.price;}cout<<"============================="<<endl;cout<<"本次应付:"<<total<<endl;return 0;
}
#include <iostream>
#include <string>
#include<iomanip>#include<vector>
#include<list>
#include<map>
#include<algorithm>
#include<array>using namespace std;
/*分析:顾客:customer属性:姓名钱包行为:购物付款查看钱包余额超市:market属性:名字货品行为:添加商品账目查看结账*///购物车
struct bar
{float price;int num;};class market
{public:market(string name){this->market_name=name;box.clear();total=0.0f;}bool add_goods(string gname,float price){if(box.find(gname)!=box.end()){return false;}else{box[gname]=price;return true;	}}float checkout(const map<string,bar>&shoppingCar){float sum=0;for(auto e:shoppingCar){cout<<e.first<<"\t"<<e.second.price<<"\t"<<e.second.num<<endl;sum=sum+e.second.num*e.second.price;}total=total+sum;cout<<"本次应付款:"<<sum<<"元"<<endl;return sum;	}float getAccount() const{return total;}map<string,float>& getBox(){return box;}private:string market_name;map<string,float> box;float total;};class customer
{public:customer(string name,float money){this->cname=name;this->wallet=money;}map<string,bar>& shopping(map<string,float>&box){static map<string,bar> shoppingCar;shoppingCar.clear();string goods_name;int goods_num;while(1){cout<<"请输入你要购买的商品名称:";cin>>goods_name;cout<<endl;if(goods_name=="exit") break;cout<<"请输入你要购买的商品数量:";cin>>goods_num;if(box.find(goods_name)!=box.end()){if(shoppingCar.find(goods_name)==shoppingCar.end()){struct bar temp;temp.price=box[goods_name];temp.num=goods_num;shoppingCar[goods_name]=temp;}else{shoppingCar[goods_name].num=shoppingCar[goods_name].num+goods_num;}}else{cout<<"查无此商品"<<endl;}}	 return shoppingCar; }bool pay(float money){float temp=this->wallet-money;if(temp>=0){	this->wallet=this->wallet-money;return true;}elsereturn false;}float getBalance()const {return wallet;}private:string cname;float wallet;};int main()
{market superMarket("华润万家");superMarket.add_goods("香肠",3);superMarket.add_goods("芙蓉王",30);superMarket.add_goods("玉米",5);superMarket.add_goods("披萨",30);superMarket.add_goods("鸡蛋",2);customer laoma("老马",300);map<string,bar>sCar= laoma.shopping(superMarket.getBox());float money=superMarket.checkout(sCar);laoma.pay(money);cout<<superMarket.getAccount();return 0;
}

 

 二、智能指针

1、简介

本质上就是一个类、智能指针其实是⼀个类,实质就是重载了->和*操作符的类,由类来实现对内存的 管理,确保即使有异常产⽣,也可以通过智能指针类的析构函数完成内存的释放。 智能指针的⾏为类似常规指针,重要的区别在于智能指针负责⾃动释放所指向的对 象。

STL提供给我们提供了四种智能指针类型,除了下边列出的三种,还有C++98标准

auto_ptr智能指针,C+11已将将其摒弃。C++11 标准新引⼊了 这 3 个智能指针:

shared_ptr : 允许多个智能指针指向同⼀个对象

unique_ptr : ⼀个指针“独占”所指向的对象

weak_ptr : 弱引⽤,指向shared_ptr所管理的对象

2、unique_ptr

unique_ptr它提供了对动态分配内存的独占所有权的管理。unique_ptr确保同⼀时 间只有⼀个unique_ptr实例可以拥有⼀个对象的指针,从⽽避免了资源的多重释放 问题。当 std::unique_ptr 被销毁时,它所指向的对象也会被⾃动销毁。

unique_ptr 智能指针是以模板类的形式提供的,unique_ptr(T 为指针所指数 据的类型),定义在头⽂件,并位于 std 命名空间中。

特点:

轻量级:没有额外的引⽤计数开销,因此效率较⾼。

不可复制: std::unique_ptr 不能被复制,但可以通过 std::move 转移 所有权。

⾃动释放: 当 unique_ptr 离开作⽤域时,它所管理的对象会被⾃动删除

#include <iostream>
#include <string>
#include<memory>
using namespace std;class stu
{
public:string name;int age;stu(){name="sdf";age=0;}~stu(){cout<<"stu析构函数"<<endl;}};int main()
{//unique_ptr<int> ptr(new int(0));//唯一智能指针通过 * 运算符来访问托管对象
//	*ptr=*ptr+10;
//	cout<<*ptr<<endl;
//	
//	unique_ptr<stu> ptr1(new stu);
//	cout<<ptr1->name<<endl;
//	cout<<(*ptr1).name<<endl;//智能指针绑定动态数组 //unique_ptr<int[]> ptr(new int[3]{11,22,33});//唯一智能指针可以通过move函数来转移接管对象的所有权,转移成功后,该指针被设置为NULLPTR
//	unique_ptr<stu> ptr1(new stu);
//	unique_ptr<stu> ptr2=std::move(ptr1);
//	cout<<ptr2->name<<endl;
//	if(ptr1==nullptr)
//		cout<<"ptr1为空指针"<<endl;
//	else
//		cout<<"ptr1不是空指针"<<endl;stu *pt=new stu;unique_ptr<stu> ptr1(pt);//	ptr1.release();//让智能指针解除对托管对象之间的绑定关系,但是不会删除绑定对象
//		if(ptr1==nullptr)
//		cout<<"ptr1为空指针"<<endl;
//	else
//		cout<<"ptr1不是空指针"<<endl;//cout<<ptr1->name;//ptr1.reset();//解除绑定的同时 将智能指针设置为NULLPTR 会删除绑定对象cout<<"=======================";//通过get方法可以获取接管对象的地址cout<<pt<<":"<<ptr1.get()<<endl;return 0;
}

http://www.lryc.cn/news/585736.html

相关文章:

  • LDO选型
  • Rust基础-part2-变量和可变类型
  • LVS-NAT模式配置
  • 期望和方差的计算
  • 深度学习×第8卷:优化器与训练流程进阶——她开始跑起来,学着一次次修正自己
  • 深度体验飞算JavaAI:一场Java开发效率的革命
  • 百度2026届校招开启,大规模发力AI的百度未来何在?
  • Telnet远程连接实验(Cisco)
  • Redis事务失败的处理机制与处理方案
  • 日历插件-FullCalendar的详细使用
  • C++:非类型模板参数,模板特化以及模板的分离编译
  • 【整数大求余草稿】2022-3-7
  • 进制转换原理与实现详解
  • Qt中QGraphicsView类应用解析:构建高效2D图形界面的核心技术
  • vue table 自定义处理 key 作为 表头
  • AUTOSAR进阶图解==>AUTOSAR_SWS_IOHardwareAbstraction
  • [精选]如何解决pip安装报错ModuleNotFoundError: No module named ‘subprocess’问题
  • Matlab裁剪降水数据:1km掩膜制作实战
  • C++STL-list
  • 这个方法的目的是检查一个给定的项目ID(projectId)是否在当前数据库中被使用(搜索全库)
  • 四、神经网络——正则化方法
  • VLM-R1 + GRPO 算法完整复现全过程日志
  • Linux修炼:权限
  • SpringCloud【OpenFeign】
  • 学习日记-spring-day46-7.11
  • 伺服驱动控制CANopen协议
  • 网络编程(基本概念)
  • 【C++篇】二叉树进阶(上篇):二叉搜索树
  • TCP详解——流量控制、滑动窗口
  • mysql的性能优化:组提交、数据页复用、全表扫描优化、刷脏页