【C++】初始化列表

前言:这个知识点的细节比较多,且有些细节不太容易理解,要做好准备哟👻

Ⅰ.构造函数的不完美😭

初始化列表,顾名思义,用列表一样的格式将其初始化。

🤔奇怪啊,构造函数的不是可以初始化嘛?为什么C++还要引入初始化列表?

唉,因为这个构造函数它在某些方面不太好使啊!

在介绍初始化列表之前,我先来把构造函数的缺陷指出来,从而让我们意识到:世界需要初始化列表。

关于构造函数的不完美,这里列出2点:

1.当自定义类型成员没有默认构造函数时,会出现一种很尴尬的场面:

class Time
{
public:Time(int time){_time = time;}
private:int _time;
};
​
class Date
{
public:Date(int day, int time){_t = time;_day = day;}
private:int _day;Time _t;  //默认构造函数会调用自定义类型的Time(int time)
};
​
int main()
{Date d1(1,1);return 0;
}

为啥尴尬?

示例化d1时,会调d1的默认构造函数(编译器自己生成的),它对于内置类型 _year不做处理,

但对于自定义类型 _t,会调用它的构造函数,此时我们自己写了,编译器不再自动生成默认的。

然而,这个Time是需要传参的,可d1并没有传参过去。

所以会编译失败。

2.没法给const常量、引用类型的成员变量初始化。

举个const常量的例子。

const常量,在声明的同时,必须初始化。

int main() {int a = 0;const int b;  //没初始化return 0;
}

它就必须得写成这样:

const int b = 0(初始值);

而构造函数没法让const常量初始化:

class Date {
public:Date(int year, int month, int day) {this->_year = year;this->_month = month;this->_day = day;}
private:const int _year;     //假如_year设定为2023,那它又该在哪初始化呢?int _month;         //这里是声明,是不可以初始化的!int _day;
};
int main() {
​return 0;
}

在Date构造函数里是没法初始化变量的。

因为类就是一张造房子的图纸,它实际并没开空间!

而初始化一个变量,是需要开空间,来保存值的。

Ⅱ.初始化列表✨

1.格式

构造函数是在函数体内初始化的,而初始化列表是在体外。

以一个冒号开始,接着是一个以逗号分隔的数据成员列表,

每个"成员变量"后面跟一个放在括号中的初始值或表达式。

be like this:Date(int year, int month, int day):_year(year),_month(month)  ,_day(day){}

Date(int month, int day):_year(2023),_month(month)   //用几个参数就传几个,_day(day){}

Date():_year(2023), _month(1),_day(1){}

2.用初始化列表 解决 构造函数的问题

刚刚我们指出,自定义类型成员(前提是没有默认构造函数)、const常量成员,都没法被构造函数初始化。

现在换上初始化列表试试:

a. 自定义类型成员
class Time
{
public:Time(int time){_time = time;}
private:int _time;
};
​
class Date
{
public:Date(int day, int time):_t(time)        //自定义类型用初始化列表{_day = day;}
private:int _day;Time _t; 
};
​
int main()
{Date d1(1,1);return 0;
}

成功初始化:

b. const常量成员
class Date {
public:Date(int month, int day) :_year(2023){this->_month = month;this->_day = day;}
private:const int _year;    int _month;         int _day;
};
​
int main() {Date d1(1, 1);   //d1、d2、d3的_year都是2023Date d2(2,2);Date d3(3,3);return 0;
}

成功初始化:

3.说明

1.每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)

这区别于构造函数,构造函数体内可以多次赋值。

//构造函数✅:

class Date {
public:Date(int year, int month, int day){_year = year;_month = month;_day = day;_year = 2000;  //多次赋值}
private:int _year;    int _month;        int _day;
};
​
int main()
{Date d1(1,1);  //d1初始化的结果为2000-1-1,而非2023-1-1return 0;
}

//初始化列表❎,编译报错:

class Date {
public:Date(int year, int month, int day):_year(year),_month(month),_day(day),_year(2000) //多次赋值{}private:int _year;    int _month;        int _day;
};

2.类中包含以下成员,必须放在初始化列表位置进行初始化:

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

3.尽量使用初始化列表初始化。

其实,无论是用初始化列表,还是函数体内初始化,对于内置类型都是无所谓的。

但对于自定义类型成员变量,一定要使用初始化列表初始化。不然连编译都通过不了。

4.初始化列表中的初始化顺序:

为成员变量在类中的声明次序

与其在初始化列表中的先后次序无关。

class Date {
public:Date() :_month(1)   //不是这个次序,_day(1),_year(2023){}
private:     //看的是这里声明的次序int _year;    int _month;         int _day;
};

不过,还是建议 声明的顺序和初始化列表的顺序 保持一致,不易错🥰


初始化列表就讲到这里。

可以发现,初始化列表 并不是 来取代构造函数的,

它是来辅助构造函数,让初始化变量 更灵活好用的。

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

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

相关文章

【Ubuntu 20.04 安装 搜狗输入法】细节注意

建议下载地址为: 搜狗拼音下载地址-Linux 也即是这个主页:适配Ubuntu20.04 安装过程根据官方文档即可 即 官方安装文档 一般不会出错

Vue2向Vue3过度Vuex状态管理工具快速入门

目录 1 Vuex概述1.是什么2.使用场景3.优势4.注意: 2 需求: 多组件共享数据1.创建项目2.创建三个组件, 目录如下3.源代码如下 3 vuex 的使用 - 创建仓库1.安装 vuex2.新建 store/index.js 专门存放 vuex3.创建仓库 store/index.js4 在 main.js 中导入挂载到 Vue 实例…

IDEA下SpringBoot指定环境、配置文件启动

1、idea下的SpringBoot启动:指定配置文件 Springboot项目有如下配置文件 主配置文件application.yml, 测试环境:application-test.yml 生产环境:application-pro.yml 开发环境:application-dev.yml 1.1.配置文件…

windows下如何搭建属于自己的git服务器

前一阵子公司需要,领导让我给我们技术部搭建一个git服务器。以前看过教程,但自己没动手做过,开始按照网上的教程来,但搭建过程中发现还是不够详细,今天给大家一个比较详细的,希望对大家有帮助。 高能预警&a…

【环境配置】Android-Studio-OpenCV-JNI以及常见错误 ( 持续更新 )

最近一个项目要编译深度学习的库,需要用到 opencv 和 JNI,本文档用于记录环境配置中遇到的常见错误以及解决方案 Invalid Gradle JDK configuration found failed Invalid Gradle JDK configuration foundInvalid Gradle JDK configuration found. Open…

工业RFID在智能半导体领域的创新驱动!

在当今科技飞速发展的时代,半导体工业作为先锋领域,正不断追求更高的生产效率和产品质量。在这一挑战背后,RFID技术应运而生,为生产过程追踪和控制,以及在线检测和质量管理带来了前所未有的创新。通过其独特的优势&…

docker,nvidia-docker安装

卸载先前的docker Docker 的旧版本被称为 docker,docker.io 或 docker-engine 。如果已安装,请卸载它们: sudo apt-get remove docker docker-engine docker.io containerd runc使用 Docker 仓库进行安装 设置仓库 更新 apt 包索引 sudo…

SemrushBot蜘蛛爬虫屏蔽方式

查看访问日志时候发现有SemrushBot爬虫 屏蔽方法: 使用robots.txt文件是一种标准的协议,用于告诉搜索引擎哪些页面可以和不能被爬取,如想禁止Googlebot爬取整个网站的话,可以在该文件中添加以下内容: User-agent: Googlebot Disallow: / 对于遵循robots协议的蜘蛛…

linux删除文件恢复

linux文件恢复救大命 早上不小心将部署文件删除了,内心十分复杂,终于找回部分损失,其中一个非常重要的点是,文件必须得是修改过或者运行过,在服务器中存在进程记录 sudo su # 进入root权限 lsof | grep deploy.py在这…

助力养殖行业数字化转型,基于深度学习模型开发构建牛脸识别系统

在我们以往接触到的项目或者是业务场景中,大多牵涉到生物特征识别的任务基本都是人脸识别,这也是目前我们每天都会接触到的应用,比如:上下班的打卡、支付时的刷脸等等,这也是比较成熟的一项AI应用。 这里我们简单对一…

记录《现有docker中安装spark3.4.1》

基础docker环境中存储hadoop3--方便后续查看 参考: 实践: export JAVA_HOME/opt/apache/jdk1.8.0_333 export SPARK_MASTER_IP192.168.0.220 export SPARK_WORKER_MEMORY4g export SPARK_WORKER_CORES2 export SPARK_EXECUTOR_MEMORY4g export HADOOP_H…

【力扣 第 360 场周赛】题解(一题待补)

目录 2833. 距离原点最远的点2834. 找出美丽数组的最小和2835. 使子序列的和等于目标的最少操作次数TODO 2836. 在传球游戏中最大化函数值 这场比赛排名第 1 - 1000 名的参赛者 可获「NIO 蔚来」简历内推机会,比有的场次前十才给容易多了。 2833. 距离原点最远的点…