重生之我要学C++第五天
这篇文章主要内容是构造函数的初始化列表以及运算符重载在顺序表中的简单应用,运算符重载实现自定义类型的流插入流提取。希望对大家有所帮助,点赞+收藏+评论,支持一下吧!
目录
构造函数进阶理解
1.内置类型成员在参数列表中的定义
2.自定义类型成员在参数列表中的定义
3.初始化列表解决的三大问题
(1)类中的引用成员变量
编辑
(2)const成员变量
(3)自定义类型成员没有默认构造函数时的问题
运算符重载的应用
(1)顺序表中的运算符重载
(2)自定义类型的流插入流提取
构造函数进阶理解
在上一篇文章中,我们已经了解过构造函数的作用:初始化对象。
注意,构造函数仅仅说是初始化对象,那么在初始化前一定有为对象分配内存空间,即成员变量的定义。什么时候完成成员变量的定义呢?那就是构造函数内部的初始化列表。
下面给出初始化列表的语法规则:
class A//类A
{
public:A(){cout<<"调用A的默认构造 A()"<<endl;_a=i;}A(int i){cout << "调用A的带参构造 A(int)" << endl;_a = i;}
private:int _a;
};
class Date//类Date
{
public:Date(int year = 1, int month = 1, int day = 1)//构造函数:_year(year),//构造函数的初始化列表(为成员变量分配空间)_month(month),_day(day),a(){//构造函数函数体}
private://成员变量的声明int _year;//内置类型成员int _month;int _day;A a;//自定义类型成员
};
初始化列表是构造函数不可缺少的,就算不手动写编译器也会默认添加。默认添加的初始化列表为内置类型分配空间,但不指定值(随机值)。对自定义类型成员会调用自定义类型的默认构造函数。
public:Date(int year = 1, int month = 1, int day = 1)//构造函数/*:_year(), //编译器默认添加,会为成员分配内存空间,是随机值_month(),_day(),a()*/ //对自定义类型会调用自定义类型的默认构造函数{}
1.内置类型成员在参数列表中的定义
此时上面的构造函数未手动添加初始化列表,这时创建一个对象
Date d1;
d1.Print();
打印d1的内置类型成员变量。

是随机值,因为默认初始化列表只为内置类型成员变量分配了内存空间,并没有给成员变量赋值。
此时赋值操作既可以在手动添加的初始化列表中完成,也可以在函数体中完成赋值。
(1).手动添加的初始化列表中完成赋值
Date(int year = 1, int month = 1, int day = 1)//构造函数:_year(year),_month(month),_day(day){}
Date d1;
d1.Print();
运行结果:

(2).函数体内完成赋值
public:Date(int year = 1, int month = 1, int day = 1)//构造函数/* :_year(),_month(),_day()*/ //默认参数列表{_year = year;_month = month;_day = day;}
Date d1;
d1.Print();
运行结果:

总结:内置类型成员变量的定义(分配内存空间)只能在初始化列表中一次性完成,不管写不写都会有这个过程,手动写可以顺便在定义时赋值。不写编译器的默认参数列表会将成员变量定义为随机值,之后再函数体中再次赋想要的值。
2.自定义类型成员在参数列表中的定义
当我们不手动添加初始化列表,默认的初始化列表会调用自定义类型成员的默认构造函数
例如:当构造函数是这样时
Date(int year = 1, int month = 1, int day = 1)//构造函数//:_year(),//默认初始化列表//_month(),//_day(),//a() 默认构造函数的调用{//构造函数函数体}
Date d1;
运行结果:

当我们手动写初始化列表时,就可以选择性的调用自定义类型的构造函数,可以是带参的,也可以是默认构造函数。
Date(int year = 1, int month = 1, int day = 1)//构造函数:_year(year),//默认初始化列表_month(month),_day(day),a(2) //选择调用带参构造函数
此时
Date d1;
运行结果

总结:默认构造函数对自定义类型自动调用自定义类型的默认构造方法本质是默认构造函数的默认初始化列表调用自定义类型的默认构造方法。只要构造方法使用默认初始化列表,对自定义类型就会调用它的默认构造方法。反之,手动添加初始化列表就可以选择性的调用自定义类型的构造方法。
3.初始化列表解决的三大问题
(1)类中的引用成员变量
引用在定义的时候必须初始化,否则会出现编译错误,详见重生之我要学C++第二天_无极太族的博客-CSDN博客
类中的成员都是在初始化列表中定义的,如果成员有引用类型就必须在初始化列表中初始化。
#include<iostream>
using namespace std;
class A
{
public :A(int a){_a = a;//初始化}
private:int& _a;
};
int main()
{int tmp = 2;A a(tmp);return 0;
}
此时,引用_a的定义在默认初始化列表中已经完成,在构造函数函数体中在赋值初始化会导致编译错误(定义处未初始化)。
解决方案:在构造函数中手动添加初始化列表,在初始化列表中定义和初始化一并进行。
A(int a)
:
_a(a)
{}
(2)const成员变量
const成员变量容易出问题和引用的原理相同。都是定义处必须初始化。
(3)自定义类型成员没有默认构造函数时的问题
我们知道,构造函数不写初始化列表时,默认初始化列表会调用自定义类型的默认构造函数
默认构造函数:

详见:重生之我要学C++第四天_无极太族的博客-CSDN博客
但是如果此时这个自定义类型没有默认构造方法,会出现编译错误。
这时候就必须手动添加参数列表,选择性的调用自定义类型具有的构造方法。
运算符重载的应用
第四天我们学习了运算符重载,在这里举两个例子让读者感受到运算符重载的魅力!
(1)顺序表中的运算符重载
先写一个简陋的顺序表
#include<iostream>
using namespace std;
class Sequence
{
public:Sequence(){//初始化_a = (int*)malloc(4 * sizeof(int));_size = 0;_capcity = 4;}void Push(int x){//检查容量:此处忽略_a[_size] = x;_size++;}void Print(){for (int i = 0; i < _size; i++){cout << _a[i] << " ";}}
private:int* _a;int _size;int _capcity;
};
int main()
{Sequence s;//创建顺序表s.Push(1);//尾插三个数据s.Push(2);s.Push(3);//打印顺序表s.Print();return 0;
}
我们可以在类内部将[ ]重载一下
int& operator[](int i)
{return _a[i];
}
此时,顺序表内的元素就可以像数组一样访问:
int main()
{Sequence s;//创建顺序表s.Push(1);//尾插三个数据s.Push(2);s.Push(3);//打印顺序表cout << s[0]<<s[1]<<s[2]<<endl;return 0;
}
重载[ ]后,可以让顺序表更加形象,大大增强了代码的可读性。
(2)自定义类型的流插入流提取
用Date类来举例
#include<iostream>
using namespace std;
class Date//类Date
{
public:Date(int year=1, int month=1, int day=1)//构造函数{_year = year;_month = month;_day = day;}void Print(){cout << _year << "年" << _month << "月" << _day << "天" << endl;}
private://成员变量的声明int _year;//内置类型成员int _month;int _day;
};
int main()
{Date d1(1,1,2);d1.Print();return 0;
}
可以使用Print函数来打印日期

但是如果这样也可以打印日期,是不是会觉得赏心悦目
cout<<d1<<endl;
下面我们就利用运算符重载来实现这个想法。
#include<iostream>
using namespace std;class Date//类Date
{
public:friend ostream& operator<<(ostream& out, Date& d);//将此函数声明为类Date的友元函数Date(int year=1, int month=1, int day=1)//构造函数{_year = year;_month = month;_day = day;}void Print(){cout << _year << "年" << _month << "月" << _day << "天" << endl;}
private://成员变量的声明int _year;//内置类型成员int _month;int _day;
};
ostream& operator<<(ostream& out, Date& d)
{out << d._year << "年" << d._month << "月" << d._day << "天";return out;
}
int main()
{Date d1(1, 1, 2);cout << d1;return 0;
}
运行结果:

这里cout是ostream类的对象,将运算符重载写为全局函数就可以调换cout对象和d对象的位置。使用友元函数使得在类外面的函数可以访问类的private成员。下篇文章会介绍友元函数。
今天的分享就到这里啦,如果对大家有用的话,希望程序猿们可以三连支持一下,会继续分享知识!谢谢!
相关文章:
重生之我要学C++第五天
这篇文章主要内容是构造函数的初始化列表以及运算符重载在顺序表中的简单应用,运算符重载实现自定义类型的流插入流提取。希望对大家有所帮助,点赞收藏评论,支持一下吧! 目录 构造函数进阶理解 1.内置类型成员在参数列表中的定义 …...
复习之linux高级存储管理
一、lvm----逻辑卷管理 1.lvm定义 LVM是 Logical Volume Manager(逻辑卷管理)的简写,它是Linux环境下对磁盘分区进行管理的一种机制。 逻辑卷管理器(LogicalVolumeManager)本质上是一个虚拟设备驱动,是在内核中块设备和物理设备…...
HuggingGPT Solving AI Tasks with ChatGPT and its Friends in Hugging Face
总述 HuggingGPT 让LLM发挥向路由器一样的作用,让LLM来选择调用那个专业的模型来执行任务。HuggingGPT搭建LLM和专业AI模型的桥梁。Language is a generic interface for LLMs to connect AI models 四个阶段 Task Planning: 将复杂的任务分解。但是这里…...
java工程重写jar包中class类覆盖问题
结论:直接在程序中复写jar中的类即可 原因:一般我java工程是运行在tomcat容器中,tomcat容易在加载我们工程类和jar包是的优先级为: 我们工程的class 先于 我们工程lib下的jar 重复的类只加载一次,加载我们复写后的类后…...
Mybatis基于注解与XML开发
文章目录 1 关于SpringBoot2 关于MyBatis2.1 MyBatis概述2.2 MyBatis核心思想2.3 MyBatis使用流程3 MyBatis配置SQL方式3.1 基于注解方式3.1.1 说明3.1.2 使用流程3.1.3 常用注解 3.2 基于XML方式3.2.1 相比注解优势3.2.2 使用流程3.2.3 常用标签 1 关于SpringBoot SpringBoot…...
数字化转型导师坚鹏:数字化时代扩大内需的8大具体建议
在日新月异的数字化时代、复杂多变的国际化环境下,扩大内需成为推动经济发展的国家战略,如何真正地扩大内需?结合本人15年的管理咨询经验及目前实际情况的深入研究,提出以下8大具体建议: 1、制定国民收入倍增计划。结…...
M1/M2 通过VM Fusion安装Win11 ARM,解决联网和文件传输
前言 最近新入了Macmini M2,但是以前的老电脑的虚拟机运行不起来了。😅,实际上用过K8S的时候,会发现部分镜像也跑不起来,X86的架构和ARM实际上还是有很多隐形兼容问题。所以只能重新安装ARM Win11,幸好微软…...
Linux中显示系统正在运行的进程的命令
2023年7月29日,周六上午 在Linux中,ps命令用于显示当前系统中正在运行的进程, ps应该是processes snapshot(进程快照)的缩写。 以下是ps命令的常见用法和示例: 显示当前用户的所有进程:ps 显示…...
vite中安装less
使用vite创建的项目,默认是没有安装less的 如果直接在style中书写less 会报下图错误: 解决方案: npm install --save less 在package.json中查看是否安装成功 安装完成刷新页面,问题解决...
Aduino中eps环境搭建
这里只记录Arduino2.0以后版本:如果有外网环境,那么可以轻松搜到ESP32开发板环境并安装,如果没有,那就见下面操作: 进入首选项,将esp8266的国内镜像地址填入,然后保存,在开发板中查…...
python——案例二 求两个数的和
#案例二 求两个数的和 num1input(请输入第一个数字:) num2input(请输入第二个数字:) sumfloat(num1)float(num2) #计算公式 print(sum) #显示结果 输入num11、num22得到结果sum3...
一文了解 Android 车机如何处理中控的旋钮输入?
前言 上篇文章《从实体按键看 Android 车载的自定义事件机制》带大家了解了 Android 车机支持自定义输入的机制 CustomInputService。事实上,除了支持自定义事件,对于中控上常见的音量控制、焦点控制的旋钮事件,Android 车机也是支持的。 那…...
小红书推广 方法总结
大家好,我是网媒智星,今天跟大家分享一下小红书的推广方法和经验。 一、平台简介 1、什么是小红书? 小红书是一个消费决策/生活方式平台,用户可以通过图片、文案、视频等方式分享美好生活。 2、用户画像 - 2亿月活跃…...
通讯录的实现(超详细)——C语言(进阶)
目录 一、创建联系人信息(结构体) 二、创建通讯录(结构体) 三、define定义常量 四、打印通讯录菜单 五、枚举菜单选项 六、初始化通讯录 七、实现通讯的的功能 7.1 增加加联系人 7.2 显示所有联系人的信息 7.3 单独查…...
3D 渲染技巧-如何创建高质量写实渲染?
掌握创建高质量建筑渲染和任何 3D 渲染的艺术是一项复杂且需要技巧的工作,通常需要多年的经验和实践。实现逼真的结果需要仔细考虑众多因素,并避免可能导致缺乏真实性的假渲染效果的常见错误。 避免常见错误 - 提升渲染游戏的技巧 在追求创建真正逼真的…...
fastadmin采坑之获取当前登录admin用户的信息
在controller层里想要获取当前登录admin用户的信息 print_r($this->auth->getUserInfo());但是有个问题 我在fa_admin表中添加了新的字段,这个方法获取不到新字段的数值,具体也没有去研究估计跟方法有关 然后我直接用模型去获取数据,简…...
【Spring AOP + 自定义注解 + 动态数据源 实现主从库切换读写分离】—— 案例实战
💧 S p r i n g A O P 主从数据源切换 读写分离 自定义注解案例实战! \color{#FF1493}{Spring AOP 主从数据源切换 读写分离 自定义注解 案例实战!} SpringAOP主从数据源切换读写分离自定义注解案例实战!💧 …...
【LeetCode每日一题合集】2023.7.24-2023.7.30
文章目录 771. 宝石与石头代码1——暴力代码2——位运算集合⭐(英文字母的long集合表示) 2208. 将数组和减半的最少操作次数(贪心 优先队列)2569. 更新数组后处理求和查询⭐⭐⭐⭐⭐(线段树)TODO2500. 删除…...
《吐血整理》进阶系列教程-拿捏Fiddler抓包教程(14)-Fiddler断点(breakpoints)实战,篡改或伪造数据
1.简介 上一篇主要就讲解和分享Fiddler断点的理论和操作,今天宏哥就用具体例子,将上一篇中的理论知识实践一下。而且在实际测试过程中,有时候需要修改请求或响应数据,或者直接模拟服务器响应,此时可以使用fiddler进行…...
ELK + Fliebeat + Kafka日志系统
参考: ELKFilebeatKafka分布式日志管理平台搭建_51CTO博客_elk 搭建 ELK 日志分析系统概述及部署(上)-阿里云开发者社区 ELK是三个开源软件的缩写,分别表示:Elasticsearch , Logstash, Kibana , 它们都是开源软件。…...
wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...

