c++(四)

c++(四)

  • 运算符重载
    • 可重载的运算符
    • 不可重载的运算符
    • 运算符重载的格式
    • 运算符重载的方式
      • 友元函数进行运算符重载
      • 成员函数进行运算符重载
  • 模板
    • 定义的格式
    • 函数模板
    • 类模板
  • 标准模板库
    • vector向量容器
    • STL中的list
    • map向量容器

运算符重载

运算符相似,运算符相同,操作数不同,与返回值无关的一组函数
目的:让参与运算的数据类型更多样化—>c++可拓展性的体现
在这里插入图片描述

可重载的运算符

在这里插入图片描述

不可重载的运算符

在这里插入图片描述

运算符重载的格式

在这里插入图片描述

运算符重载的方式

友元函数进行运算符重载

案例1:复数 a+bi

#include <iostream>
using namespace std;
class CComplex
{
public:CComplex(int rear = 2, int img = 3) :rear(rear), img(img){cout << "CComplex(int,int)" << endl;}~CComplex(){cout << "~CComplex()" << endl;cout << this << endl;}void show(){cout << this->rear << "+" << this->img << "*i" << endl;}friend CComplex operator+(CComplex& obj1, CComplex& obj2);
private:int rear;//实部int img;//虚部
};
CComplex operator+(CComplex& obj1, CComplex& obj2)
{CComplex obj3;cout << &obj3 << endl;obj3.rear = obj1.rear + obj2.rear;obj3.img = obj1.img + obj2.img;return obj3;
}
int main()
{CComplex c1(1,2);cout << &c1 << endl;CComplex c2(2,3);cout << &c2 << endl;//Complex c3 = c1 + c2;//隐式调用CComplex c3 = operator+(c1, c2);//显示调用cout << &c3 << endl;c3.show();return 0;
}

在这里插入图片描述
案例2:重载前置++

#include <iostream>
using namespace std;
//使用友元函数实现++符号的自增
class CComplex
{
public:CComplex(int rear = 1, int img = 1);~CComplex();void show();friend void operator++ (CComplex& demo);
private:int rear;int img;
};
CComplex::CComplex(int rear, int img)
{this->rear = rear;this->img = img;cout << "构造" << endl;
}
CComplex::~CComplex()
{cout << "析构" << endl;
}
void CComplex::show()
{cout << this->rear << "+" << this->img << "*i" << endl;
}
void operator++ (CComplex& demo)
{++demo.rear;++demo.img;
}
int main()
{CComplex c1(2,3);//++c1;//隐式调用operator++(c1);c1.show();
}

在这里插入图片描述

成员函数进行运算符重载

案例1:重载前置++,后置++

#include <iostream>
using namespace std;
//使用成员函数实现++符号的自增,后++
class CComplex
{
public:CComplex(int rear = 1, int img = 1);~CComplex();void show();CComplex& operator++ ();CComplex& operator++(int n);
private:int rear;int img;
};
CComplex::CComplex(int rear, int img)
{this->rear = rear;this->img = img;cout << "构造" << endl;
}
CComplex::~CComplex()
{cout << "析构" << endl;
}
void CComplex::show()
{cout << this->rear << "+" << this->img << "*i" << endl;
}
CComplex& CComplex::operator++ ()
{++this->rear;++this->img;return *this;
}
CComplex& CComplex::operator++(int n)
{CComplex temp = *this;this->rear++;this->img++;return temp;
}
int main()
{CComplex c1(2, 3);//++c1;//隐式调用c1.operator++();//显示调用c1.show();CComplex c2(3, 4);c2.operator++(1).show();c2.show();
}

在这里插入图片描述
总结:
<1>友元重载参数要比成员重载的参数多一个,因为成员函数默认有一个this指针
<2>并不是所有的运算符都可以通过友元或者成员重载

cin >> 变量;//只能通过友元函数进行重载

#include <iostream>
using namespace std;
//重载cin,实现可以输入对象
class CComplex
{
private:int rear;int img;
public:void show();friend CComplex& operator >> (istream& tmp, CComplex& c1);
protected:
};void CComplex::show()
{cout << this->rear << "+" << this->img << "*i" << endl;
}
CComplex& operator>>(istream& tmp, CComplex& c1)
{cout << "rear:" << endl;tmp >> c1.rear;cout << "img:" << endl;tmp >> c1.img;return c1;
}int main()
{CComplex c1;cin >> c1;c1.show();
}

在这里插入图片描述

模板

  • 模板是支持参数化多态的工具,就是让类或者函数声明为一种通用类型,使得类中的某些数据成员或者成员函数的参数、返回值在实际使用时可以是任意类型
  • 减少代码冗余,提高开发效率

在这里插入图片描述

定义的格式

template<class/typename T>
返回值类型 函数名(参数列表)
{
;
}

函数模板

在这里插入图片描述

  • 函数模板是真正的函数吗?不是
  • 什么时候才能变成真正的函数呢?
    在这里插入图片描述
#include <iostream>
using namespace std;
template<typename T>
T MAX(T a, T b) //不占内存空间
{return a > b ? a : b;
}
int main()
{//实例化模板cout << MAX<int>(1, 2) << endl;cout << MAX<string>("hello", "c++");cout << MAX<int>(3, 4) << endl;//类型相同的模板函数只会生成一次return 0;
}

总结:
<1>调用函数时,将模板的数据类型具体化的时候,才会变成真正的函数,此时占内存空间,称为模板
函数
<2>类型相同的模板函数只会生成一次
<3>函数模板可以重载

案例:用模板实现数组的输出

#include <iostream>
using namespace std;
//模板实现数组的输出
template<typename T>
void output(T arr[],int n)
{int i;for (i = 0; i < n; i++){cout << arr[i] << " ";}cout << endl;
}int main()
{int arr[] = { 1, 2, 3, 4, 5 };int length = sizeof(arr) / sizeof(int);output<int>(arr, length);string brr[] = { "hello", "c++" };length = sizeof(brr) / sizeof(string);output<string>(brr, length);char crr[] = { 'a', 'b', 'c'};length = sizeof(crr) / sizeof(char);output<char>(crr, length);return 0;
}

在这里插入图片描述

类模板

实现:链表:带头节点的单向不循环列表
<1>节点类(数据域、指针域)
<2>链表的类(增(尾插法)、删、改、查)、头结点

#include <iostream>
using namespace std;
//结点
class linkNode
{
public:int data;linkNode* next;//构造linkNode();//析构~linkNode();
protected:
};
//操作
class Handle
{
private:linkNode* head;
public://构造Handle();//析构~Handle();//插入(尾插)void insert(int data);//查void search();protected:
};linkNode::linkNode()
{this->data = 0;this->next = nullptr;cout << "构造" << endl;
}
linkNode::~linkNode()
{cout << "析构" << endl;
}
Handle::Handle()
{this->head = new linkNode;
}
Handle::~Handle()
{}
void Handle::insert(int data)
{//创建一个新结点linkNode* pNew = new linkNode;//赋值pNew->data = data;//找尾结点linkNode* pFind = this->head;while (pFind->next != nullptr){pFind = pFind->next;}//插入pFind->next = pNew;
}
void Handle::search()
{linkNode* pFind = this->head->next;if (pFind == nullptr){return;}while (pFind != nullptr){cout << pFind->data << " ";pFind = pFind->next;}cout << endl;
}int main()
{Handle han;han.insert(10);han.insert(20);han.insert(30);han.search();return 0;
}

类模板:

#include <iostream>
using namespace std;
template <typename T>
//结点
class linkNode
{
public:T data;linkNode<T>* next;//构造linkNode();//析构~linkNode();
protected:
};
//操作
template <typename T>
class Handle
{
private:linkNode<T>* head;
public://构造Handle();//析构~Handle();//插入(尾插)void insert(T data);//查void search();protected:
};template <typename T>
linkNode<T>::linkNode()
{//this->data = 0;this->next = nullptr;cout << "构造" << endl;
}
template <typename T>
linkNode<T>::~linkNode()
{cout << "析构" << endl;
}
template <typename T>
Handle<T>::Handle()
{this->head = new linkNode<T>;
}
template <typename T>
Handle<T>::~Handle()
{}
template <typename T>
void Handle<T>::insert(T data)
{//创建一个新结点linkNode<T>* pNew = new linkNode<T>;//赋值pNew->data = data;//找尾结点linkNode<T>* pFind = this->head;while (pFind->next != nullptr){pFind = pFind->next;}//插入pFind->next = pNew;
}
template <typename T>
void Handle<T>::search()
{linkNode<T>* pFind = this->head->next;if (pFind == nullptr){return;}while (pFind != nullptr){cout << pFind->data << " ";pFind = pFind->next;}cout << endl;
}int main()
{Handle<int> han;han.insert(10);han.insert(20);han.insert(30);han.search();Handle<string> han2;han2.insert("hello");han2.insert("c++");han2.search();return 0;
}

总结:
<1>类模板中使用一个或多个虚拟类型作为其成员数据类型的时候
<2>类模板不能分文件实现

标准模板库

即标准模板库,惠普实验室开发的一系列软件的统称。它是由Alexander Stepanov、Meng Lee和DavidR Musser在惠普实验室工作时所开发出来的。STL主要是一些“容器”的集合,这些“容器”有list、vector、set、map,等等,STL也是算法和其他一些组件的集合,是世界上顶级C++程序员多年的杰作,是泛型编程的一个经典范例。

STL可分为六个部分:
容器(containers)
迭代器(iterators)
空间配置器(allocator)
配接器(adapters)
算法(algorithms)
仿函数(functors)

容器(containers)//类模板
特殊的数据结构,实现了数组、链表、队列、等等,实质是模板类
迭代器(iterators)//对象指针
一种复杂的指针,可以通过其读写容器中的对象,实质是运算符重载
算法(algorithms)//对象的操作
读写容器对象的逻辑算法:排序、遍历、查找、等等,实质是模板函数
空间配置器(allocator)
容器的空间配置管理的模板类
配接器(adapters)
用来修饰容器、仿函数、迭代器接口
仿函数(functors)
类似函数,通过重载()运算符来模拟函数行为的类
组件间的关系
container(容器) 通过 allocator(配置器) 取得数据储存空间,algorithm(算法)通过iterator(迭代器)存取 container(容器) 内容,functor(仿函数) 可以协助 algorithm(算法) 完成不同的策略变化,adapter(配接器) 可以修饰或套接 functor(仿函数)

vector向量容器

底层实现:数组
特点:<1>地址连续
<2>a、通过索引的方式去访问 b、通过迭代器访问
<3>访问方便
<4>插入、删除需要移动元素,不方便
<5>大小不固定
本质:vector是对数组的封装

#include <iostream>
#include <vector>
using namespace std;
/*
* 类似于数组
* 地址连续,可以使用索引访问,也可以使用迭代器访问,查询方便,增加和删除不方便,大小不固定
*/int main()
{//实例化vector类模板vector<string> list_vect;//增加元素//void push_back(const T& x)在容器的末尾插入一个元素list_vect.push_back("hello");list_vect.push_back("world");list_vect.push_back("c++");//访问//使用索引方式//size_type size() const;用来返回容器中元素个数for (int i = 0; i < list_vect.size(); i++){//const_reference at ( size_type n ) const;获取容器某个位置上的元素值cout << list_vect.at(i) << " ";}cout << endl;//使用迭代器访问vector<string>::iterator it;//获取第二个位置的iteratorit = ++list_vect.begin();//在某位置上增加元素list_vect.insert(it, "hahaha");//iterator begin()返回第一个元素的迭代器//iterator end()返回最后一个元素的下一个位置的迭代器for (it = list_vect.begin(); it < list_vect.end(); it++){cout << *it << " ";}cout << endl;//删除某一位置上的元素//获取第二个位置的iteratorit = ++list_vect.begin();list_vect.erase(it);for (it = list_vect.begin(); it < list_vect.end(); it++){cout << *it << " ";}cout << endl;//修改第二个位置的值/*it = ++list_vect.begin();list_vect.erase(it);it = ++list_vect.begin();list_vect.insert(it, "hahaha");*/list_vect.at(1) = "hahaha";for (it = list_vect.begin(); it < list_vect.end(); it++){cout << *it << " ";}cout << endl;return 0;
}

在这里插入图片描述

STL中的list

底层结构:双向链表
特点:
<1>内存中的地址是不连续–>不能通过索引的方式去访问–>访问效率没有vector高
<2>频繁的插入、删除不需要移动元素,效率比vector

#include <iostream>
#include <list>
using namespace std;class Stu
{
public:Stu(int sno = 1, string name = "张三") :sno(sno), name(name){cout << "构造" << endl;}~Stu(){cout << "析构" << endl;}void show(){cout << "学号:" << this->sno << ",姓名:" << this->name << endl;}
private:int sno;string name;
protected:
};
void showList(list<Stu>& list_s)
{list<Stu>::iterator it;for (it = list_s.begin(); it != list_s.end(); it++){it->show();}
}int main()
{//实例化类模板list<Stu> list_s;//插入//void push_back ( const T& x );在列表的末尾插入一个元素list_s.push_back(Stu());//void push_front ( const T& x );在列表的头部插入一个元素list_s.push_front(Stu(2, "李四"));//iterator insert ( iterator position, const T& x ); 在列表的指定位置插入一个元素list<Stu>::iterator it;it = ++list_s.begin();//获取第二个位置list_s.insert(it, Stu(3, "王五"));//查看,只能以迭代器的方式/*for (it = list_s.begin(); it != list_s.end(); it++){it->show();}*/showList(list_s);//删除//iterator erase ( iterator position );删除某个位置的元素//it = ++list_s.begin();//获取第二个位置it = list_s.begin();advance(it, 1);list_s.erase(it);//查看,只能以迭代器的方式/*for (it = list_s.begin(); it != list_s.end(); it++){it->show();}*/showList(list_s);//修改it = ++list_s.begin();//获取第二个位置list_s.erase(it);it = ++list_s.begin();//获取第二个位置list_s.insert(it, Stu(3, "王五"));//查看,只能以迭代器的方式/*for (it = list_s.begin(); it != list_s.end(); it++){it->show();}*/showList(list_s);return 0;
}

在这里插入图片描述

map向量容器

底层结构:红黑树—>二叉树的一种
以键值对的形式存储
key—>value,key值是唯一的
特点:
<1>查找的速度特别快
<2>自动按照从小到大的顺序去排序
应用场景:频繁的查找

#include <iostream>
#include <map>
using namespace std;class Stu
{
public:Stu(int sno = 1, string name = "张三") :sno(sno), name(name){cout << "构造" << endl;}~Stu(){cout << "析构" << endl;}void show(){cout << "学号:" << this->sno << ",姓名:" << this->name << endl;}void setname(string name){this->name = name;}private:int sno;string name;
protected:
};
void showList(map<int, Stu*> mymap)
{map<int, Stu*>::iterator it;for (it = mymap.begin(); it != mymap.end(); it++){cout << "key:" << it->first << " ";it->second->show();}cout << endl;
}int main()
{//实例化类模板map<int, Stu*> mymap;map<int, Stu*>::iterator it;//插入Stu stu1;mymap.insert(pair<int, Stu*>(2, &stu1));it = mymap.begin();Stu stu2(2, "王五");mymap.insert(it, pair<int, Stu*>(1, &stu2));Stu stu3(3, "李四");mymap.insert(pair<int, Stu*>(3, &stu3));showList(mymap);//删除mymap.erase(2);showList(mymap);//修改it = mymap.find(1);if (it != mymap.end()){(*it).second->setname("刘六");}showList(mymap);return 0;
}

在这里插入图片描述

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

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

相关文章

Android刮刮卡自定义控件

效果图 刮刮卡自定义控件 import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PorterDuff; import …

Linux--进程间通信(1)(匿名管道)

目录 1.了解进程通信 1.1进程为什么要通信 1.2 进程如何通信 1.3进程间通信的方式 2.管道 2.1管道的初步理解 2.2站在文件描述符的角度-进一步理解管道 2.3 管道的系统调用接口&#xff08;匿名管道&#xff09; 2.3.1介绍接口函数&#xff1a; 2.3.2编写一个管道的代…

AI Agent教育行业落地案例

【AI赋能教育】揭秘Duolingo背后的AI Agent&#xff0c;让学习更高效、更有趣&#xff01; ©作者|Blaze 来源|神州问学 引言 随着科技的迅猛发展&#xff0c;人工智能技术已经逐步渗透到我们生活的各个方面。而随着AI技术的广泛应用&#xff0c;教育培训正引领着一场新的…

微软语音使用小计

简介 使用微软语音可以实现语音转文字和文字转语音。测试了下&#xff0c;使用还是挺方便的。 使用微软语音有两种方式。一种是使用命令行的形式&#xff0c;另一种是调用SDK的方式。 适合使用语音 CLI 的情况&#xff1a; 想在极少设置且无需编写代码的情况下试验语音服务…

Vulnhub靶机 whowantsobeking :1 打靶 渗透详细过程(萌新)

Vulnhub靶机搭建配置 先搭建vulnhub靶机&#xff1a;https://www.vulnhub.com/entry/who-wants-to-be-king-1,610/ 下载镜像之后whowantsobeking.ova后&#xff0c;用VMware Workstation Pro打开依次点击文件-打开&#xff0c;选择我们刚才下载的ova文件打开&#xff0c;修改…

JavaWeb开发 2.Web开发 Web前端开发 ①介绍

内心一旦平静&#xff0c;外界便鸦雀无声 —— 24.5.27 一、初识Web前端 网页有哪些部分组成? 文字、图片、音频、视频、超链接 ...网页&#xff0c;背后的本质是什么? 前端代码前端的代码是如何转换成用户眼中的网页的? 通过浏览器转化(解析和渲染)成用户看…

表空间[MAIN]处于脱机状态

达梦数据库还原后&#xff0c;访问数据库报错&#xff1a;表空间[MAIN]处于脱机状态 解决方法&#xff1a; 1&#xff1a;检查备份文件 DMRMAN 中使用 CHECK 命令对备份集进行校验&#xff0c;校验备份集是否存在及合法。 ##语法&#xff1a;CHECK BACKUPSET <备份集目录…

小识MFC,一套设计优雅与不优雅并存的类库----小话MFC(2)

Q1&#xff1a; CPoint继承于POINT&#xff0c;这样有什么好处&#xff1f; A&#xff1a; 继承的一个最基本的好处当然就是减少代码量。CPoint和POINT内部数据一样&#xff0c;只是一个提供了更多的方法来操作对象。 typedef struct tagPOINT {LONG x;LONG y; } POINT, *P…

小程序大能量:盲盒平台搭建与营销策略

一、引言 在移动互联网的浪潮下&#xff0c;小程序以其轻量级、即用即走的特点&#xff0c;成为了商家与消费者沟通的新桥梁。盲盒经济作为近年来兴起的消费趋势&#xff0c;结合小程序平台&#xff0c;不仅为用户带来了全新的购物体验&#xff0c;也为商家带来了更多的商业机…

【管理咨询宝藏115】某大型电力集团5年战略发展报告终稿

本报告首发于公号“管理咨询宝藏”&#xff0c;如需阅读完整版报告内容&#xff0c;请查阅公号“管理咨询宝藏”。 【管理咨询宝藏115】某大型电力集团5年战略发展报告终稿 【格式】PDF版本 【关键词】战略规划、大型国企、战略报告 【核心观点】 - 战略领导人敏锐的直觉和城…

【乐吾乐3D可视化组态编辑器】模型类型与属性

编辑器地址&#xff1a;3D可视化组态 - 乐吾乐Le5le 本章主要为您介绍模型的属性功能。 一个模型至少会包含一个节点&#xff08;Node&#xff09;&#xff0c;从节点类型上可以分为转换节点&#xff08;TransformNode&#xff09;、网格&#xff08;Mesh&#xff09;、实例网…

5.27作业

定义自己的命名空间my_sapce&#xff0c;在my_sapce中定义string类型的变量s1&#xff0c;再定义一个函数完成对字符串的逆置。 #include <iostream> #include <string.h>using namespace std; namespace my_space {string s1;void RevString(string &s1); } v…

OrangePi AIpro 开箱初体验及语音识别样例

OrangePi AIpro 开箱初体验及语音识别样例 一、 前言 首先非常感谢官方大大给予这次机会&#xff0c;让我有幸参加此次活动。 OrangePi AIpro联合华为精心打造&#xff0c;采用昇腾AI技术路线&#xff0c;具体为4核64位处理器AI处理器&#xff0c;集成图形处理器&#xff0c;…

【JavaScript】P3 JavaScipt 注释方法、结束符、输入输出

小结&#xff1a; Js 注释&#xff1a; 单行注释&#xff1a;//多行注释&#xff1a;/* */ Js 结束符&#xff1a; 分号; 可以加也可以不加 Js 输入输出&#xff1a; 输入&#xff1a;prompt()输出&#xff1a;document.write() 在页面中打印&#xff0c;console.log() 在控制…

浅谈金融行业数据安全分类分级

数据安全管理是一项从上而下的、多方配合开展的工作。在进行数据安全管理组织架构建设时&#xff0c;需要从上而下建设&#xff1b;从而全面推动数据安全管理工作的执行和落地&#xff1b;以保证数据安全的合法合规、并长效推动业务的发展和稳定运行。 金融行业机构应设立数据…

【Sql Server】随机查询一条表记录,并重重温回顾下存储过程的封装和使用

大家好&#xff0c;我是全栈小5&#xff0c;欢迎来到《小5讲堂》。 这是《Sql Server》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。 温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 目录 前言随机查询语…

自定义CSS属性(@property)解决自定义CSS变量无法实现过渡效果的问题

且看下面的代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>demot</title&g…

Python批量docx或doc文档转换pdf

说明&#xff1a; 1、因为项目需要&#xff0c;需要手动将十几个word文档转换成pdf文档 2、python请安装3.9.0以上&#xff0c;否则一些依赖库无法正常用 #! /usr/bin/python3 # -*- coding: utf-8 -*-import os import comtypes.client# 批量将docx文件转换pdf文件 def docx_t…

第十二周 5.21面向对象的三大特性(封装、继承、多态)(二)

三、多态 1.理解: (1)多态:父类型的引用存储不同子类型的对象 父类类名 引用名 new 子类类名(); 引用 对象 父类型 子类型 …

Java面试八股之AQS对资源的共享方式

AQS对资源的共享方式 AQS设计了一套灵活的机制&#xff0c;不仅支持独占&#xff08;Exclusive&#xff09;锁模式&#xff0c;也支持共享&#xff08;Shared&#xff09;锁模式&#xff0c;使得资源可以被一个或者多个线程以不同的方式访问。这两种模式通过控制一个内部的vol…