【C++】再识构造函数:初始化列表新方式

欢迎来到CILMY23的博客

🏆本篇主题为: 再识构造函数:初始化列表新方式

🏆个人主页:CILMY23-CSDN博客

🏆系列专栏:Python | C++ | C语言 | 数据结构与算法 | 贪心算法 | Linux

🏆感谢观看,支持的可以给个一键三连,点赞关注+收藏。


写在前头:

在之前我们花了大篇幅了解了构造函数,包括但不限于构造函数的详解,构造函数和析构函数的顺序,以及构造函数中特殊的拷贝构造函数。那这次的构造函数又会带给我什么惊喜呢?


目录

再见构造函数

1️⃣ 构造函数赋值

2️⃣ 初始化列表的概念

3️⃣ 为什么会有初始化列表? 

4️⃣ 初始化列表的特点 

5️⃣ 构造函数新的写法

6️⃣ explicit关键字 

7️⃣ 多参数类型的隐式转换 


再见构造函数

1.1  构造函数赋值

在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。

class Student
{
public://无参构造函数Student(){strcpy(_name, "xxxxxx");_age = 0;strcpy(_ID, "xxxxxxx");}void Print(){cout << "学生姓名:" << _name << endl;cout << "学生年龄:" << _age << endl;cout << "学生学号:" << _ID << endl;}
private:char _name[20];int _age;char _ID[20];
};int main()
{Student stu1;//调用了无参的构造函数stu1.Print();return 0;
}

虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称为对对象中成员变量 的初始化,构造函数体中的语句只能将其称为赋初值,而不能称作初始化。因为初始化只能初始 化一次,而构造函数体内可以多次赋值

1.2  初始化列表的概念

初始化列表是C++中的一个功能,允许在构造函数中直接初始化成员变量,而非在构造函数体内赋值。初始化列表直接跟在构造函数的参数列表后面,以冒号开始后面紧跟一个或多个用逗号分隔的初始化表达式。这些表达式直接对成员变量或自定义类型进行初始化。

例如:这里有个学生类,我们要用初始化列表。(在这里对字符的拷贝我们仍然采用C的方法来实现,利用strncpy或者strcpy,在之后我们会用string来实现这些)

class Student {
public:// 使用初始化列表来初始化_ageStudent(const char* name, int age, const char* ID) : _age(age) {// 为_name和_ID赋值strncpy(_name, name, sizeof(_name) - 1);_name[sizeof(_name) - 1] = '\0'; strncpy(_ID, ID, sizeof(_ID) - 1);_ID[sizeof(_ID) - 1] = '\0'; }private:char _name[20];int _age;char _ID[20];
};int main()
{Student student1("Alice", 20, "1234567890");student1.Print();return 0;
}

1.3 为什么会有初始化列表? 

 例如:就像下面这段代码一样,有些类的成员是必须要在初始化的时候定义的,这里的_n = -1;是会报错的。就比如const成员是这样的。那哪个地方是初始化的呢?那它就需要去构造函数去找空间给它初始化,但也会有安全性的问题,所以有了初始化列表这个概念。初始化列表是每个成员变量定义初始化的位置。

顺序是先走上面的初始化列表,然后再走函数体内的赋值修改,能用初始化列表就用初始化列表。

class Student 
{
public://Student(const char* name, int age, const char* ID) //    : _age(age) //{//    //赋值修改//    strncpy(_name, name, sizeof(_name) - 1);//    _name[sizeof(_name) - 1] = '\0'; //}//构造函数Student(const char* name, int age){strncpy(_name, name, sizeof(_name) - 1);_name[sizeof(_name) - 1] = '\0';_age = age;_n = -1; // 无法修改}private://声明char _name[20];int _age = 1; //缺省值const int _n;
};int main() 
{//对象实例化Student student1("Alice", 20);return 0;
}

1.4 初始化列表的特点 

  1. 每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)
  2. 类中包含以下成员,必须放在初始化列表位置进行初始化,这三个在函数体内不能初始化

    ✔️引用成员变量
    ✔️const成员变量
    ✔️自定义类型成员(且该类没有默认构造函数时)

  3. 尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量, 一定会先使用初始化列表初始化。
  4. 成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后 次序无关 

这些特点如下所示: 

class A
{
public:A(int x)//初始化列表:_a(1){//赋值修改_a = x;}private:int _a;
};class Student
{
public://初始化列表是每个成员变量定义初始化的位置//能用初始化列表就用初始化列表Student(const char* name, int age, int &x): _age(age), _n(1), _aa(1)//显式调用构造函数, ref(x){strncpy(_name, name, sizeof(_name) - 1);_name[sizeof(_name) - 1] = '\0'; }private://声明char _name[20];int _age = 1; //缺省值//必须走初始化列表//1. const 成员 //2. 引用成员变量//3. 自定义类型成员const int _n;int& ref;A _aa;
};int main()
{//对象实例化int x = 0;Student student1("Alice", 20,x);return 0;
}

 1.5 构造函数新的写法

构造函数结合初始化列表后,我们可以写成main函数中的另外两种cc的形式。 

class C
{
public:C(int x = 0):_x(x){}
private:int _x;
};class B
{
public:B():_p(2),_p1((int*)malloc(sizeof(4)*10)){if (_p1 == nullptr){perror("malloc fail");}}
private://缺省值是给初始化列表的int _p = 1;int* _p1 = (int*)malloc(sizeof(4));
};int main()
{B bb;//构造函数的写法C cc1(1);//2构造一个临时对象,再拷贝构造C cc2 = 2;return 0;
}

 其实通过这个例子我们可以发现,单参数构造函数支持隐式类型的转换,2构造一个临时对象,然后再拷贝构造

如果遇到同一个表达式连续步骤的构造,一般会被编译器优化。 

隐式类型转换是有好处的,例如我们在栈传参的时候,可以直接将int类型的4转换成自定义类型。

1.6 explicit关键字 

如果你不想让上述这种隐式类型转换发生,那你就可以加一个关键字 - explicit。 

  

1.7 多参数类型的隐式转换 

在目前的C++11中,支持多参数类型的隐式转换,C++98还不支持,用花括号括起来。


总结:

  • 初始化列表直接跟在构造函数的参数列表后面,以冒号开始后面紧跟一个或多个用逗号分隔的初始化表达式
  • 顺序是先走上面的初始化列表,然后再走函数体内的赋值修改
  • 当出现函数赋值修改缺省值,和初始化列表的时候,推荐是能用初始化列表就用初始化列表。
  • 有些成员必须走初始化列表,1. const 成员 2. 引用成员变量 3. 自定义类型成员(没有默认构造的自定义类型成员)
  • 成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后 次序无关
  • 缺省值是给初始化列表的
  • 单参数构造函数支持隐式类型的转换
  • 临时变量具有常性,需要加const修饰。
  • 构造函数不仅可以构造与初始化对象,对于单个参数或者除第一个参数无默认值其余均有默认值的构造函数,还具有类型转换的作用。
  • explicit 可以限制隐式类型的转换
  • C++11 支持多参数类型的隐式类型转换

感谢各位同伴的支持,本期C++就讲解到这啦,如果你觉得写的不错的话,可以给个一键三连,点赞,关注+收藏,若有不足,欢迎各位在评论区讨论。  

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

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

相关文章

ubuntu18.04的安装Anaconda步骤

参考&#xff1a;http://t.csdnimg.cn/7KX4p 这个链接写的很全&#xff0c;我主要记以下自己的步骤 1https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ 这个链接下载的Anaconda3-2023.03-0-Linux-x86_64.sh 然后进入下载的目录&#xff0c; bash Anaconda3-2023.0…

SpringBoot集成Seata分布式事务OpenFeign远程调用

Docker Desktop 安装Seata Server seata 本质上是一个服务&#xff0c;用docker安装更方便&#xff0c;配置默认&#xff1a;file docker run -d --name seata-server -p 8091:8091 -p 7091:7091 seataio/seata-server:2.0.0与SpringBoot集成 表结构 项目目录 dynamic和dyna…

用户登录认证和权限授权(SpringSecurity、JWT、session)

文章目录 前言一、登录认证1. 问题引入2. Session2.1 实现原理2.2 过滤器Filter2.3 上下文对象 3. JWT3.2 实现步骤3.3 拦截器 HandlerInterceptorAdapter3.4 上下文对象 4. Session VS JWT 二、权限授权1. 权限类型1.1 页面权限&#xff08;菜单项权限&#xff09;1.2 ACL模型…

C++入门必读-Qt设计与运行界面不一致问题

界面不一致问题 在Qt设计界面中&#xff0c; 会经常出现设计的窗口和实际运行窗口布置问题。如下图所示&#xff0c;设计界面大小可以调整&#xff0c;但是运行界面的默认是一定大小。 问题解决方案 在我们的主函数(main&#xff09;中添加这么一段代码&#xff0c;注意Qt版本大…

centos7中如何全局搜索一下nginx的配置文件?

在CentOS 7中搜索Nginx的配置文件&#xff0c;你可以使用一些常用的命令行工具&#xff0c;比如find、grep等。这些工具可以帮助你在文件系统中查找文件&#xff0c;也可以用来查找Docker容器内部的文件&#xff0c;只要你知道如何访问容器的文件系统。 1. 搜索系统中的Nginx配…

石墨烯材料商汉烯科技授权世强硬创,代理产品具备高导热/导电特点

近日&#xff0c;武汉汉烯科技有限公司&#xff08;下称“汉烯科技”&#xff0c;英文&#xff1a;HANXI TECH&#xff09;与世强先进&#xff08;深圳&#xff09;科技股份有限公司&#xff08;下称“世强先进”&#xff09;达成授权代理合作&#xff0c;面向锂电新能源、电子…

【循环程序设计-谭浩强适配】(适合专升本、考研)

无偿分享学习资料&#xff0c;需要的小伙伴评论区或私信dd。。。 无偿分享学习资料&#xff0c;需要的小伙伴评论区或私信dd。。。 无偿分享学习资料&#xff0c;需要的小伙伴评论区或私信dd。。。 完整资料如下&#xff1a;纯干货、纯干货、纯干货&#xff01;&#xff01;…

Java入门基础学习笔记21——Scanner

在程序中接收用户通过键盘输入的数据&#xff1a; 需求&#xff1a; 请在程序中&#xff0c;提示用户通过键盘输入自己的姓名、年龄、并能在程序中收到这些信息&#xff0c;怎么解决&#xff1f; Java已经写好了实现程序&#xff0c;我们调用即可。 API&#xff1a;Applicat…

车载电子电器架构 —— 应用软件开发(中)

车载电子电器架构 —— 应用软件开发(中) 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明…

韵搜坊(全栈)-- 前后端初始化

文章目录 前端初始化后端初始化 前端初始化 使用ant design of vue 组件库 官网快速上手&#xff1a;https://www.antdv.com/docs/vue/getting-started-cn 安装脚手架工具 进入cmd $ npm install -g vue/cli # OR $ yarn global add vue/cli创建一个项目 $ vue create ant…

全新Transformer模型:全球与局部双重突破!

DeepVisionary 每日深度学习前沿科技推送&顶会论文分享&#xff0c;与你一起了解前沿深度学习信息&#xff01; 引言&#xff1a;探索视觉变换器在对象重识别中的全局与局部特征 在对象重识别&#xff08;Re-ID&#xff09;的研究领域中&#xff0c;如何有效地从不同时间…

网络网络层之(5)IPv6协议

网络网络层之(5)IPv6协议 Author: Once Day Date: 2024年5月12日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文档可参考专栏&#xff1a;通信网络技术_Once-Day…

答辩PPT框架如何搭建?文心一言AI辅助构建

很多快要毕业的同学在做答辩PPT的时候总是感觉毫无思路&#xff0c;一窍不通。但这并不是你们的错&#xff0c;对于平时没接触过相关方面&#xff0c;第一次搞答辩PPT的人来说&#xff0c;这是很正常的一件事。一个好的答辩PPT可以根据以下分为以下几部分来写。 1.研究的背景和…

2.1 软件工程

第2章 信息技术知识 2.1 软件工程 现状&#xff1a; 开发软件的规模越来越大复杂度越来越高用户需求并不十分明确缺乏软件开发方法和工具方面的有效支持 软件成本日益增长、开发进度难以控制、软件质量无法保证、软件维护困难等问题日益突出。人们开始用工程的方法进行软件…

geotrust ov泛域名证书2990

Geotrust是一家正规的CA证书颁发机构&#xff0c;致力于为个人以及企事业单位开发者提供安全可靠的数字证书产品&#xff0c;维护了个人博客网站、企业官网、商城网站以及银行等金融网站的数据安全&#xff0c;营造了一种健康的网络环境。今天就随SSL盾小编了解Geotrust旗下的O…

Ansys Zemax|基于Alvarez自由曲面透镜的光学变焦系统

附件下载 联系工作人员获取附件 Alvarez变焦是一个出色的光学系统&#xff0c;其中由自由曲面镜头的横向位移提供了光学变焦。这篇文章解释了Alvarez变焦镜头的主要原理&#xff0c;并提供了在Zemax OpticStudio中对Alvarez变焦镜头的计算和建模演示。 什么是Alvarez变焦镜头…

Android PreferenceActivity可以自动设置的Activity

1、介绍 PreferenceActivity 是一个抽象类&#xff0c;继承自ListActivity ,该类封装了SharedPreferences. PreferenceActivity 提供了一些常用的设置项如,与普通组件一样&#xff0c;这些配置项既可以从XML文件创建&#xff0c;也可以从代码创建. 每一个设置项标签有一个andro…

MyBatis——MyBatis 参数处理

一、单个简单类型参数 简单类型包括&#xff1a; byte short int long float double char Byte Short Integer Long Float Double Character String java.util.Date java.sql.Date parameterType 属性&#xff1a;告诉 MyBatis 参数的类型 MyBatis 自带类型自动推断机制…

揭秘APP广告:变现逻辑全解析!

在当今的移动互联网时代&#xff0c;APP广告变现已经成为了各大应用开发者的主要营收来源之一。然而&#xff0c;随着科技的发展、用户行为的变化以及广告市场趋势的演进&#xff0c;APP广告变现逻辑也正在不断地进行优化和调整。本文将基于当前市场和技术趋势&#xff0c;为大…

【技巧】如何查看RAR格式文件?

RAR是一种压缩文件格式&#xff0c;想要查看RAR文件&#xff0c;如果电脑系统自带解压缩功能&#xff0c;可以直接双击打开查看&#xff1b;也可以使用解压缩软件&#xff0c;比如常见的WinRAR、7-ZIP软件&#xff0c;来查看RAR文件 。 以WinRAR软件为例&#xff0c;安装好软件…