当前位置: 首页 > 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.dtcms.com/a/274764.html

相关文章:

  • 【C/C++】动态内存分配:从 C++98 裸指针到现代策略
  • PyTorch武侠演义 第一卷:初入江湖 第1章:武林新秀遇Tensor - 张量基础
  • 技术突破与落地应用:端到端 2.0 时代辅助驾驶TOP10 论文深度拆解系列【第九篇(排名不分先后)】
  • 飞书CEO谢欣:挑战巨头,打造AI新时代的Office
  • Rail开发日志_6
  • Python类型注解中的`Optional`:深入理解难点解析(进阶版)
  • EndNote快速入手指南
  • CDN 加速与安全防护:双剑合璧的技术协同
  • manifest.json只有源码视图没其他配置
  • Tomcat问题:启动脚本startup.bat中文乱码问题解决
  • 实现临界区互斥的基本方法
  • MyBatis 进阶:连接池、动态 SQL 与多表关联查询
  • 不可告人的秘密- 1.0版 (字符串加密解密工具)
  • c++26新功能—copyable_function
  • windows内核研究(系统调用 二)
  • vue使用printJS实现批量打印及单个打印 避免空白页
  • Kubernetes 高级调度
  • SSM与SpringBoot面试题
  • Gin 中常见参数解析方法
  • 解锁48V USB-C供电潜力,慧能泰重磅推出PD3.2 DRP芯片HUSB253
  • 使用 SSH 连接 GitHub
  • UC浏览器PC版自2016年后未再更新不支持vue3
  • Grok-4 发布会图文总结
  • 【常见分布及其特征(1)】引言
  • 异步复习(线程)
  • CS144 lab2 tcp_receiver
  • Linux入门篇学习——Linux 编写第一个自己的命令,make 工具和 makefile 文件
  • C语言实现Linux命令行工具:VI和CAT
  • 飞算JavaAI进阶:重塑Java开发范式的AI革命
  • LGA核心板贴装指南:关键细节决定产品成败