类和对象(3)
文章目录
- 1.回顾上节
- 2. 拷贝构造
- 3. 运算符重载(非常重要)
- 4. 赋值运算符重载
1.回顾上节
默认成员函数:我们不写,编译器自动生成。我们不写,编译器不会自动生成
默认生成构造和析构:
- 对于内置类型不做处理
- 对于自定义类型会调用对应的构造/析构。
2. 拷贝构造
#include <iostream>
using namespace std;
class Date
{
public:Date(int year=1, int month=1, int day=1){_year = year;_month = month;_day = day;}//拷贝构造,函数名和类名相同//拷贝构造的参数为什么不能是传值?//C++自定义类型的成员在这个地方传值需要调用拷贝构造,无穷无尽//因此自定义类型必须调用拷贝构造,所以要用引用&。最好加constDate(const Date& d){_year = d._year;_month = d._month;_day = d._day;}void Print(){cout << _year << "年" << _month << "月" << _day << "日" << endl;}
private:int _year;int _month;int _day;
};
int main()
{Date d1;Date d2(d1);d1.Print();d2.Print();//这时改变_year等会改变d1return 0;
}
以下为不调用拷贝构造时,会默认生成拷贝构造
内置类型会处理,因此日期类不需要自己去写拷贝构造
自定义类型会去调用他的拷贝构造
Stack st1;Stack st2(st1);//栈中保持后进先出,后定义的先析构。//st1变成野指针。
指向同一块空间的问题:
- 插入删除数据会互相影响
- 析构两次,程序崩溃。
默认的拷贝:
浅拷贝/值拷贝
**深拷贝:**让各自有各自独立的空间,开另外的空间,把值拷贝下来。
更深入层次的拷贝
typedef int DataType;
class Stack
{
public:Stack(size_t capacity = 10){_array = (DataType*)malloc(capacity * sizeof(DataType));if (nullptr == _array){perror("malloc申请空间失败");exit(-1);}_size = 0;_capacity = capacity;}
void Push(const DataType& data)
{_array[_size] = data;_size++;
}
Stack(const Stack& st)//深拷贝
{_array = (DataType*)malloc(sizeof(DataType) * st._capacity);if (nullptr == _array){perror("malloc申请空间失败");exit(-1);//直接终止程序}//拷贝数组空间上的值memcpy(_array, st._array, sizeof(DataType) * st._size);_size = st._size;_capacity = st._capacity;
}
~Stack()
{if (_array){free(_array);_array = nullptr;_capacity = 0;_size = 0;}
}
private:DataType *_array;size_t _size;size_t _capacity;};
int main()
{Stack st1;st1.Push(1);st1.Push(2);st1.Push(3);st1.Push(4);Stack st2(st1);//栈中保持后进先出,后定义的先析构。//没有写拷贝构造,编译器自动生成了一个return 0;
}
什么情况下需要写拷贝构造呢?
不能用指针来衡量,如果自己实现了析构函数释放了空间,就需要实现拷贝构造。
- 对于内置类型完成浅拷贝/值拷贝–按byte一个个拷贝
- 自定义类型,去调用这个成员拷贝构造/赋值重载
2种大方向的特性
typedef int DataType;
class Stack
{
public:Stack(size_t capacity = 10){_array = (DataType*)malloc(capacity * sizeof(DataType));if (nullptr == _array){perror("malloc申请空间失败");exit(-1);}_size = 0;_capacity = capacity;}
void Push(const DataType& data)
{_array[_size] = data;_size++;
}
Stack(const Stack& st)
{//拷贝构造对内置类型完成值拷贝或者浅拷贝。cout << "Stack(const Stack& st)" << endl;_array = (DataType*)malloc(sizeof(DataType) * st._capacity);if (nullptr == _array){perror("malloc申请空间失败");exit(-1);//直接终止程序}//拷贝数组空间上的值memcpy(_array, st._array, sizeof(DataType) * st._size);_size = st._size;_capacity = st._capacity;
}
~Stack()
{if (_array){free(_array);_array = nullptr;_capacity = 0;_size = 0;}
}private:DataType *_array;size_t _size;size_t _capacity;};
//对于自定义类型,不需要写拷贝构造和构造。不写编译器会自动生成构造函数,构造函数符合我们的需求
class MyQueue
{
public://默认生成构造和析构//默认生成拷贝构造
private:Stack _pushST;Stack _popST;int _size = 0;//缺省值,用缺省值处理
};
int main()
{Stack st1;st1.Push(1);st1.Push(2);st1.Push(3);st1.Push(4);Stack st2(st1);//栈中保持后进先出,后定义的先析构。//没有写拷贝构造,编译器自动生成了一个MyQueue q1;//调用了拷贝构造MyQueue q2(q1);return 0;
}
那些场景存在拷贝构造
Date d2(d1);
Date d3=d1;//拷贝构造
传返回值的过程中能用引用就用引用,减少拷贝。除非就是想让他自己调用拷贝构造,拷贝一份独立的出来
参数基本都可以用引用,返回值不一定。局部对象不能用引用。
Date Test(Date d)
{Date temp(d);return temp;
}
3. 运算符重载(非常重要)
为了增强程序的可读性,是具有特殊函数名的函数,也有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似
- 比较日期大小
内置类型可以比较大小,自定义类型不可以。 - 运算符重载和函数重载无关:
函数重载是支持参数名相同,参数不同的函数,随时可以用
运算符重载:自定义类型对象可以使用运算符。
两个地方都用了重载,但两个地方没有关联 - 运算符重载:实现一个函数。新增一个关键字operator加操作符,有参数有返回值。
- 参数和返回值根据运算符确定。有的有返回值有的没有。
- 运算符有几个操作数就有几个参数
class Date
{
public:Date(int year=1, int month=1, int day=1){_year = year;_month = month;_day = day;}//private:int _year;int _month;int _day;};bool operator==(const Date& d1, const Date& d2)//运算符重载可以实现在全局。
{return d1._year == d2._year&& d1._month == d2._month&& d1._day == d2._day;
}
int main()
{Date d1(2023, 9, 14);Date d2(2023, 9, 14);cout<<operator==(d1, d2)<<endl;cout <<( d1 == d2) << endl;//全局函数,转换成调用这个函数operator==(d1,d2);和上一行一样//运算符优先级<<高于==return 0;
}
当放成私有时
class Date
{
public:Date(int year=1, int month=1, int day=1){_year = year;_month = month;_day = day;}
private:int _year;int _month;int _day;};
直接把函数放在类里面。类外面受到访问限定符的限制,放到类里面就解决问题了。但是会报错
其中还有隐藏的参数(2个):this
成员函数调用的方式也不同了。
//d1==d2转换为d1.operator==(d2)
bool operator==(const Date& d){//this:d1;d:d2return this->_year == d._year&& _month == d._month&& _day == d._day;}
cout<<d1.operator==(d2)<<endl;cout <<( d1 == d2) << endl;//成员函数转换成调用这个函数d1.operator==(d2);和上一行一样
运算符重载
- 函数名:operator+运算符或操作符
- 返回值类型/参数:根据需求调用
- 不能乱接其他符号创造一个新的操作符,如:operator@
- 必须有一个类类型参数**(自定义类型)**
- 不能对内置类型重载,其含义不能改变。如内置类型的整型——,不能改变其含义
- 作为类成员函数重载时,其形参看起来比操作数目少1,因为成员函数的第一个参数为隐藏的this
- .* :: sizeof ?:(三目运算符) .(成员访问) 注意以上5个运算符不能重载,这个经常在笔试选择题中出现
//b1<b2小测
bool operator<(const Date& d)
{if (_year < d._year){return true;}else if (_year == d._year && _month < d._month){return true;}else if (_year == d._year && _month == d._month && _day < d._day){return true;}else{return false;}
}
//b1<=b2复用,根据上面有<有=
bool operator<=(const Date& d)
{return *this < d || *this == d;
}
//b1>b2,取反。
bool operator>(const Date& d)
{return !(*this <= d) ;
}
4. 赋值运算符重载
d1=d2;//是一种拷贝
//d1=d2
void operator=(const Date& d)//不用引用不会无穷递归,但会白白走一次拷贝构造,所以最好加上引用
{_year = d._year;_month = d._month;_day = d._day;
}
d3=d2=d1;//编译不通过d1赋值给d2,d2的返回值传给d3
连续赋值,从右往左赋值。i=j=k; k赋值给j,返回j
Date& operator=(const Date& d)
{_year = d._year;_month = d._month;_day = d._day;//*this是d1return *this;//出了作用域还在,应该加引用。//返回值是为了支持连续赋值,保持运算符的特性。
}
d1=d1
自己给自己赋值,可以加一个判断
Date& operator=(const Date& d)//引用
{if(this!=&d)//取地址,this是左操作数的地址,d是右操作数的别名,地址相同则不用自己给自己赋值{_year = d._year;_month = d._month;_day = d._day;}return *this;
}
+=支持连续赋值,只要支持连续赋值就都有返回值。。
前置++,d1.operator();
后置++,d2.operator(int);
int仅仅是为了占位,和牵制重载区分
//++d1;
Date& Date::operator++()
{Date tmp(*this);*this+=1;return tmp;
}
//d1++
Date Date::operator++(int)
{Date tmp(*this);*this+=1;return tmp;
}
对于内置类型,前置和后置++没有区别
对于自定义类型,**前置++**效率高,后置++还要拷贝
相关文章:
类和对象(3)
文章目录 1.回顾上节2. 拷贝构造3. 运算符重载(非常重要)4. 赋值运算符重载 1.回顾上节 默认成员函数:我们不写,编译器自动生成。我们不写,编译器不会自动生成 默认生成构造和析构: 对于内置类型不做处理对…...
C++下基于粒子群算法解决TSP问题
粒子群优化算法求解TSP旅行商问题C(2020.11.12)_jing_zhong的博客-CSDN博客 混合粒子群算法(PSO):C实现TSP问题 - 知乎 (zhihu.com) 一、原理 又是一个猜答案的算法,和遗传算法比较像,也是设…...
vue3 ElementUI Switch before-change自动调用问题
使用 :beforeChange 这个属性 但是这个属性不能直接传值 如果直接传值依然会自动调用,需要使用自执行函数来****传值 解决 <el-switchv-model"rows[index].ifInjection":before-change"() > beforeChange(row)"/> :before-change"() > b…...
【chromium】windows 获取源码到本地
从github的chromium 镜像git clone 到2.5G失败了官方说不能,要去 windows_build_instructions vs2017和19都是32位的 vs2022是x64的 vs2022_install You may also have to set variable vs2022_install to your installation path of Visual Studio 2022,...
Nacos-Go-Sdk代码逻辑解析
文章目录 初始化服务,获取nacosClient获取配置源码逻辑 获取json配置发布配置监听配置变化源码逻辑listenConfigExecutor调度longPullinglongPullingcallListener监听表 中 配置 的 结构 监听功能的调用逻辑 初始化服务,获取nacosClient Nacos Client Co…...
检测opencv是否安装成功
winr打开命令提示符窗口: 输入 : python,进入python模块; 然后输入 import cv2出现>>>就代表opencv安装成功了; 同样的,也可以检测numpy等是否安装成功 最后输入 : exit() 退出python模块...
如果你是独立开发者,你是先写前端还是先写后端?
当我们站在独立开发的路口时,一个重要的抉择就摆在了我们面前:是先着手前端开发还是后端开发?这看似简单的问题,却蕴含着许多深刻的考虑和决策。无论你是准备构建一个复杂的分布式系统还是一个引人入胜的用户界面,接下…...
Pytorch intermediate(四) Language Model (RNN-LM)
前一篇中介绍了一种双向的递归神经网络,将数据进行正序输入和倒序输入,兼顾向前的语义以及向后的语义,从而达到更好的分类效果。 之前的两篇使用递归神经网络做的是分类,可以发现做分类时我们不需要使用时序输入过程中产生的输出&…...
C++零碎记录(十)
17. 继承对象内存 17.1 查询继承对象所占内存 #include <iostream> using namespace std; #include<string>//继承中的对象模型class Base { public:int m_A; protected:int m_B; private:int m_C; };//公共继承 class Son:public Base {int m_D; };//利用开发人…...
人类学习 vs. 机器学习
摘要: 机器学习与人类学习的范式有一定的联系. 本文发掘这些联系, 作用是指导人类的学习. 1. 什么是学习? 对于人类而言, 学习是改造大脑皮层的过程. 我们会发现, 不同人学习不同东西的能力也不一样, 如有些人数学厉害, 有些人音乐厉害. 同时, 也有些牛人, 学习到了学习的方…...
【LeetCode-中等题】15. 三数之和
文章目录 题目方法一:哈希表 题目 方法一:哈希表 将四数之和 借助哈希表简化成两数之和 class Solution {public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {int res 0; //结果集数量Map<Integer,Integer> map n…...
Apache Tomcat漏洞复现
文章目录 弱口令启动环境漏洞复现 本地文件包含启动环境漏洞复现 弱口令 启动环境 来到vulhub/tomcat/tomcat8/靶场 cd vulhub/tomcat/tomcat8/安装环境并启动: sudo docker-compose up -d && sudo docker-compose up -d修改端口后启动: su…...
C++模版基础
代码地址 gitgithub.com:CHENLitterWhite/CPPWheel.git 专栏介绍 本专栏会持续更新关于STL中的一些概念,会先带大家补充一些基本的概念,再慢慢去阅读STL源码中的需要用到的一些思想,有了一些基础之后,再手写一些STL代码。 (如果你…...
解决 Elasticsearch 分页查询记录超过10000时异常
查询结果中 hits.total.value 值最大为10000的限制 解决方法: 1、请求设置rest_total_hits_as_inttrue 注意参数需要放在请求头上 builder.addHeader("rest_total_hits_as_int","true"); 2、修改setting的值 #设置返回最大记录条数为1000000 PUT /in…...
百度千帆大模型文心一言api调用
注册百度智能云账号并申请文心千帆大模型资格 https://login.bce.baidu.com/ https://cloud.baidu.com/product/wenxinworkshop 创建应用用于获取access_token 创建应用成功后,可以获取到API Key和Secret Key 获取access_token curl https://aip.baidubce.com/oauth/2.0/to…...
关于HTTP协议的概述
HTTP 的报文大概分为三大部分。第一部分是请求行,第二部分是请求的首部,第三部分才是请求的正文实体。 POST 往往是用来创建一个资源的,而 PUT 往往是用来修改一个资源的。 Accept-Charset,表示客户端可以接受的字符集。防止传过…...
ATFX汇市:8月名义与核心CPI走势分化,美国通胀率算升高还是降低?
ATFX汇市:据美国劳工部昨日公布的数据,8月份,美国名义CPI增速最新值3.7%,高于前值3.2%,高于预期值3.6%,显示高通胀问题有抬头迹象。同一时间公布的8月核心CPI年率最新值4.3%,低于前值4.7%&#…...
c++ 中的函数指针
以下图片演示了c中函数指针的用法。如下图可见,把函数地址赋值给函数指针,用函数名或者函数名的地址,都可以,c编译器不报错。即 ptr f 和 ptr &f 都对。但准确的话,函数名就是地址,在编译时候&#x…...
奶牛个体识别 奶牛身份识别
融合YOLOv5s与通道剪枝算法的奶牛轻量化个体识别方法 Light-weight recognition network for dairy cows based on the fusion of YOLOv5s and channel pruning algorithm 论文链接 知网链接 DOI链接 该文章讨论了奶牛花斑、光照条件、不同剪枝方法、不同剪枝率对准确率的影响…...
【力扣每日一题】2023.9.13 检查骑士巡视方案
目录 题目: 示例: 分析: 代码: 题目: 示例: 分析: 题目给我们一个n*n大小的矩阵,矩阵的元素表示骑士已经行动的次数,问我们骑士能不能按照矩阵里元素顺序来巡视整个…...
【Vue】关于CSS样式绑定整理
因突发奇想设计一款组件,需要根据属性动态绑定样式,故而整理一些Vue的动态绑定样式方法(传参绑定类似,不做过多叙述),仅供参考.方式一: 直接在元素上绑定具体样式方式二: 定义属性对象,绑定到style,可以在style中使用定义的变量方式二: 通过引入自定义组件引入style数据,直接绑…...
Sql语句大全--更新
今天抽空整理下项目中的Sql语句 项目中用到的Sql语句大全 Update 语句 Update 语句 Update语句update OLASF1.LLB set CBBTHCC 52 WHERE CBPOLNUMC201728534update OLASF1.LLB set CBBTHCC 01 WHERE CBPOLNUMC201728534update OLASF1.LB set CBBTHCC 01 WHERE CBPOLNUMC…...
Java面试八股文宝典:序言
序言: Java作为一门广泛应用于企业级应用开发的编程语言,一直以来都是技术面试中的重要话题。无论您是刚刚踏入编程世界的新手,还是经验丰富的Java开发工程师,都需要通过面试来展示自己的技能和知识。 在面试中,除了…...
【多线程案例】单例模式
单例模式是设计模式的一种,先谈谈什么是设计模式? 大家应该都知道棋谱、剑谱之类的,就是一些“高手”在经历过长期的累计之后,更具经验写出的具有固定套路的处理“方法”,只要按照这个套路来,在对局之中必然…...
阿里云部署SpringBoot项目启动后被杀进程的问题
阿里云部署SpringBoot项目启动后被杀进程的问题 最近部署在公司虚拟主机上的SpringBoot项目频繁被杀,这个虚拟主机是个杂货铺,部署着各种项目,时间跨度还大,不同的人负责,个人自扫门前雪,不管他人瓦上霜&a…...
git仓库推送错误
错误背景 从github克隆仓库后,想推送到gitee,在推送时遇到 error: src refspec master does not match any. error: failed to push some refs to <REMOTE_URL>解决方法 rm -rf .github git init git add -A git commit -m "init for gite…...
计网第五章(运输层)(三)
一、UDP协议和TCP协议的对比 1、UDP无连接,TCP面向连接 使用UDP协议的通信双方可以随时发送数据,使用TCP协议的通信双方必须先进行3次握手建立连接,才能发送数据,最后还要进行4次挥手才能释放连接。 2、UDP支持单播、多播以及广…...
OpenCV 07(图像滤波器)
一、卷积 什么是图片卷积? 图像卷积就是卷积核在图像上按行滑动遍历像素时不断的相乘求和的过程 步长 步长就是卷积核在图像上移动的步幅. 上面例子中卷积核每次移动一个像素步长的结果, 如果将这个步长修改为2, 结果会如何? 为了充分扫描图片, 步长一般设为1. padding …...
uniapp项目实践总结(十三)封装文件操作方法
导语:在日常 APP 开发过程中,经常要进行文件的保存、读取列表以及查看和删除文件等操作,接下来就看一下具体的方法。 目录 原理分析方法实现实战演练案例展示 原理分析 主要是以下 API。 uni.saveFile:保存文件到本地缓存列表…...
程序地址空间
✅<1>主页::我的代码爱吃辣 📃<2>知识讲解:Linux——程序地址空间 ☂️<3>开发环境:Centos7 💬<4>前言:我们一直随口就能说出来的栈区,堆区,常量…...
电子商务网站推广主要方式/whois查询 站长工具
简介: 最近小编去网上注册某个论坛账号的时候,注册的时候居然要输入邮箱账号用来激活账号,但是我需要的资料却只有这个论坛才有,但是我只是这次找我需要的资料,以后可能都不会登陆这个网站了,实在是不想泄漏自己的邮箱账号,毕竟这是个人隐私,所以我特地上网找下有没有在线接收邮…...
wordpress用户注册邮件内容自定义/哪些网站有友情链接
1、测试用例的设计方法有哪些?请阐述判定表设计测试用例的步骤。 答:等价类划分,边界值分析,错误推断法,因果图法,正交表分析法,场景分析法。 判定表设计测试用例的步骤:确定规则的个…...
做景观要用的植物网站/2022年新闻热点摘抄
我想在python文件中附加每一行,例如: File.txt Is it funny? Is it dog? 预期结果 Is it funny? Yes Is it dog? No 假设是,否.我这样做: with open(File.txt, a) as w: w.write("Yes") 但它会附加在文件末尾.并非每一行. 编辑1 with open…...
东莞东城网站建设/互联网广告行业分析
为什么80%的码农都做不了架构师?>>> 数据结构 简单动态字符串SDS(Simple Dynamic String) 使用sdshdr结构体保存字符串长度,使获取字符串长度时间复杂度为O(n)动态空间管理动态扩张机制(字符串变长后自动触发…...
攀枝花市住房和城乡建设局网站/爱用建站官网
canvas的绘制是以画布大小为准的。 canvas的默认画布大小为300150。 设置canvas画布大小的方法: // 方法一 <canvas id"test" width"100px" height"100px"></canvas>// 方法二 <canvas id"test"></…...
做印刷的网站有哪些/抓关键词的方法10条
ubuntu环境:nginxrtmp下载安装搭建下载安装包nginxpcrezlibopensslnginx-rtmp-module安装nginx解压压缩包安装nginx测试nginx复制文件修改nginx的参数rtmp模块http模块下载安装包 nginx Nginx是一款轻量级服务器/反向代理服务器及电子邮件代理服务器,并…...