C++之初始化列表详细剖析

一、初始化列表定义

初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式。

class Date
{
public:
	Date(int year, int month, int day)
		: _year(year)
		, _month(month)//初始化列表
		, _day(day)
	{}
private:
	int _year;
	int _month;
	int _day;
};

二、初始化列表内在作用的剖析

不知道大家有没有想过这样一个问题,成员函数明明可以在函数内部对成员变量进行赋值,那为什么还要搞出初始化列表这个东西呢?这个时候就需要我们对初始化列表有一个更加深刻的理解了。

我们知道,在一个类被设计出来的时候,它里面定义的成员变量只是变量的声明,没有为其分配空间。我们也知道,类定义出一个对象是在主函数中定义的,而创建出来的这个对象其中的成员变量其实是在初始化列表中定义的。那么假设我们创建出来的类的成员变量中含有引用类型或者是被const修饰时(引用类型和const修饰的变量在定义时就必须为其赋初始值),就像下面这个代码:

 如果我们定义的类内部的成员变量中含有引用类型或者是被const修饰,而在成员函数体内部再对其赋初始值,就相当于_ref和_n两个变量定义和赋初始值分离了,但我们明确地知道引用类型或者是被const修饰的变量在定义时就必须为其赋初始值,所以编译器会报未初始化的错误。上面图片中的代码还可以写的更明确一点,就相当于下面这种形式:

 五个成员变量全部定义和赋初始值分开,一般的内置类型是支持这种行为的。就像是这样:

int main()
{
	int a;
	a = 10;//可以
	int& n;
	n = a;//报错
	const int m;
	m = 10;//报错
	return 0;
}

所以正确的方法应该是:类内部的成员变量中含有引用类型或者是被const修饰时,引用类型或者是被const修饰的成员变量必须用初始化列表赋初值(定义时就赋初值)。

class Date
{
private:
	int _year;
	int _month;
	int _day;
	int& _ref;
	const int _n;

public:
	Date(int year, int month, int day)
		:_year()
		,_month()
		,_day()
		,_ref(month)
		,_n(1)
	{
		this->_year = year;
		this->_month = month;
		this->_day = day;
	}
};

三、类中成员变量含有自定义类型的情况

很好理解,自定义也必须使用初始化列表进行初始化,如果自定义类型没有显示地调用初始化列表,那么自定义类型就会去调用它的默认构造函数,如果没有默认构造函数,就会编译报错。

#include <iostream>
using namespace std;


class A
{
private:
	int _a;

public:
	A(int a = 0)
	{
		this->_a = a;
	}
};


class Date
{
private:
	int _year;
	int _month;
	int _day;
	A aa;
	int& _ref;
	const int _n;

public:
	Date(int year, int month, int day)
		:_year()  //aa没有显示地调用初始化列表,会去调用它的默认构造函数
		, _month()//剩下的三个成员没有写出来定义,但是它也会定义,只是内置类型给的随机值
		, _day()  //自定义类型会去调用它的默认构造函数
		,_ref(month)
		,_n(1)
	{
		this->_year = year;
		this->_month = month;
		this->_day = day;
	}
};


//编译没有报错
int main()
{
	Date d1(2023, 11, 2);
	return 0;
}

 _a被初始化为了0。还是上面这段代码,如果将A(int a = 0)改成A(int a),编译就会报错,因为没有合适的默认构造函数。

所以自定义类型在使用初始化列表的时候,建议要显示地传参去调用指定的构造函数。

四、初始化列表使用的建议以及小点

尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,
一定会先使用初始化列表初始化。
但是我们能不能什么地方都用初始化而都不在函数体内部赋初始值呢?答案是不行的。初始化列表可以解决百分之九十的问题,但对于一些像判断之类的语句还是要放在函数体内部的。像下面这个例子:
class Date
{
private:
	int _year;
	int _month;
	int _day;
	int* _aa;

public:
	Date(int year, int month, int day)
		:_year(year)  //aa没有显示地调用初始化列表,会去调用它的默认构造函数
		, _month(month)//剩下的三个成员没有写出来定义,但是它也会定义,只是内置类型给的随机值
		, _day(day)  //自定义类型会去调用它的默认构造函数
		,_aa(new int [10])
	{

		if (_aa == nullptr)
		{
			perror("new fail");
			exit(-1);
		}
	}

	~Date()
	{
		delete[] _aa;
	}
};


int main()
{
	Date d1(2023, 11, 2);
	return 0;
}

这里有一个小点需要注意:. 成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关。

class A
{
public:
	A(int a)
		:_a1(a)
		, _a2(_a1)
	{}

	void Print() 
	{
		cout << _a1 << " " << _a2 << endl;
	}
private:
	int _a2;
	int _a1;
};


int main() 
{
	A aa(1);
	aa.Print();
}

上面代码_a2比_a1先声明,所以_a2先初始化,用_a1初始化_a2,此时_a1为随机值,所以初始化完_a2为随机值,再用1初始化_a1,_a1为1。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

华纳云:centos系统中怎么查看cpu信息?

在CentOS系统中&#xff0c;我们可以使用一些命令来查看CPU的详细信息。下面介绍几个常用的命令&#xff1a; 1. lscpu lscpu命令可以显示CPU的架构、型号、核心数、线程数、频率等信息。 # lscpu 执行以上命令后&#xff0c;会输出类似以下内容&#xff1a; 2. cat /proc/…

3D医学三维技术影像PACS系统源码

一、系统概述 3D医学影像PACS系统&#xff0c;它集影像存储服务器、影像诊断工作站及RIS报告系统于一身,主要有图像处理模块、影像数据管理模块、RIS报告模块、光盘存档模块、DICOM通讯模块、胶片打印输出等模块组成&#xff0c; 具有完善的影像数据库管理功能&#xff0c;强大…

Oil Crop Science:DAP-seq技术揭示花生中AhTWRKY24和AhTWRKY106转录因子下游调控基因

2023年6月4日&#xff0c;青岛农业大学草业学院宋辉教授课题组的研究成果&#xff0c;发表在Oil Crop Science期刊上&#xff0c;文章题目为Identification of the target genes of AhTWRKY24 and AhTWRKY106 transcription factors reveals their regulatory network in Arach…

【好书推荐】AI时代架构师修炼之道:ChatGPT让架构师插上翅膀

目录 前言 ChatGPT对架构师工作的帮助 快速理解和分析需求 提供代码建议和解决方案 辅助系统设计和优化 提高团队协作效率 如何使用ChatGPT提高架构师工作效率 了解用户需求和分析问题 编码实践和问题解决 系统设计和优化建议 团队协作和沟通效率提升 知识管理和文…

K8s集群

统一时间&#xff1a;ntpdate(都做) ntpdate -b ntp1.aliyun.com */1 * * * * /usr/sbin/ntpdate -b ntp1.aliyun.com systemctl status docker vi /etc/docker/daemon.json systemctl restart docker m: vim kubernetes.sh cat >> /etc/yum.repos.d/kubernetes.repo…

Windows系统搭建网盘神器filebrowser结合内网穿透实现公网访问

Windows系统搭建网盘神器filebrowser结合内网穿透实现公网访问 文章目录 Windows系统搭建网盘神器filebrowser结合内网穿透实现公网访问前言1.下载安装File Browser2.启动访问File Browser3.安装cpolar内网穿透3.1 注册账号3.2 下载cpolar客户端3.3 登录cpolar web ui管理界面3…

C++动态内存检查工具 - AddressSanitizer

参考 https://www.qt.io/blog/2013/04/17/using-gccs-4-8-0-address-sanitizer-with-qt https://doc.qt.io/qt-6/qmake-variable-reference.html#qmake-lflags AddressSanitizer是gcc编译器套件的一部分(gcc版本 > 4.8)&#xff0c;只要在编译器调用中添加-fsanitizeaddre…

AtCoder abc143

D - Triangles 排序后two pointer # -*- coding: utf-8 -*- # time : 2023/6/2 13:30 # author : yhdutongwoo.cn # desc : # file : atcoder.py # software : PyCharmimport bisect import copy import sys from sortedcontainers import SortedList from coll…

Android开发知识学习——从Retrofit原理来看HTTP

文章目录 Retrofit 使用方法简介Retrofit 源码结构总结扔物线读源码的思路与方式 Retrofit 使用方法简介 导包 implementation com.squareup.retrofit2:retrofit:最新版本创建一个 interface 作为 Web Service 的请求集合&#xff0c;在里面用注解 &#xff08;Annotation&…

Spring Boot整合Swagger

&#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;程序员老茶 &#x1f64a; ps:点赞&#x1f44d;是免费的&#xff0c;却可以让写博客的作者开心好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#xff0c;…

新建Git仓库后!如何将本地项目直接推送上到git仓库中的详细教程!

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、Git新建仓库二、来到你的本地仓库 前言 我们在git新建仓库后&#xff0c;如何直接在本地的项目文件夹中直接推送到git仓库中呢&#xff01;那么下面是详细…

HTTP 协议请求头 If-Match、If-None-Match 和 ETag

概述 在 HTTP 协议中&#xff0c;请求头 If-Match、If-None-Match、If-Modified-Since、If-Unmodified-Since、If-Range 主要是为了解决浏览器缓存数据而定义的请求头标准&#xff0c;按照协议规范正确的判断和使用这几个请求头&#xff0c;可以更精准的处理浏览器缓存&#x…

《Pytorch新手入门》第二节-动手搭建神经网络

《Pytorch新手入门》第二节-动手搭建神经网络 一、神经网络介绍二、使用torch.nn搭建神经网络2.1 定义网络2.2 torch.autograd.Variable2.3 损失函数与反向传播2.4 优化器torch.optim 三、实战-实现图像分类(CIFAR-10数据集)3.1 CIFAR-10数据集加载与预处理3.2 定义网络结构3.3…

QT+SQLite数据库配置和使用

一、简介 1.1 SQLite&#xff08;sql&#xff09;是一款开源轻量级的数据库软件&#xff0c;不需要server&#xff0c;可以集成在其他软件中&#xff0c;非常适合嵌入式系统。Qt5以上版本可以直接使用SQLite&#xff08;Qt自带驱动&#xff09;。 二、下载和配置 2.1 SQLite下载…

Clion 下载、安装、使用教程,附详细图文(2023年亲测可用)

文章目录 一、下载Clion二、安装教程三、安装MinGW方法一、直接下载MinGW安装① 下载MinGW② 配置Clion 方法二、使用Dev cpp安装① 安装Dev cpp② 配置Clion 四、常用快捷键 大家好&#xff0c;今天为大家带来的是 Clion 的下载&#xff0c;安装&#xff0c;使用教程&#xff…

HTML样式CSS、图像

HTML样式-CSS: CSS (Cascading Style Sheets) 用于渲染HTML元素标签的样式。CSS可以通过以下方式添加到HTML中&#xff1a;1&#xff09;、内联方式&#xff1a;在HTML元素中使用“style”属性&#xff1b;2&#xff09;、内部样式表&#xff1a;在HTML文档头部<head>区…

揭秘!AI加持双十一电商盛宴,带你解锁更多营销新玩法

从2009年到2023年&#xff0c;每年年终的双11大促都是如期而至&#xff0c;而且几乎每一次双11都能给电商行业带来创新和改变。今年是中国电商行业的第15个双11&#xff0c;也是人工智能&#xff08;AI&#xff09;在电商领域大规模应用的第一个双11。在这15年的发展历程中&…

【ArcGIS微课1000例】0077:ArcGIS生成经纬网(shp格式)

使用ArcGIS制图的时候,可以很方便的生成经纬网、方里网及参考格网,但是在需要shp格式的经纬网,进一步在南方cass中使用经纬网的时候,就需要单独生成了。 如下图所示为全球大陆矢量数据,我们基于该数据来生成全球指定间距的经纬网数据。 在ArcGIS中,生成经纬网和方里网均…

玩了一下 Jenkins,最新版本 + JDK11

背景 今年五月的时候玩了一下 Jenkins&#xff0c;最新版本 2.414.3 &#xff0c;JDK 11 。本机有两个 JDK&#xff0c;只放到 Tomcat 里面了&#xff0c;看到了一个启动页面&#xff0c;后面有其他事情就忘记了。最近又想起来&#xff0c;觉得还是应该玩一下这么有技术含量的…

音频行业广告变现,如何破圈升级,解锁收益密码

市场规模不断扩大 音频行业伴随互联网发展多年&#xff0c;是消费者闲暇时间的娱乐项目之一。在行业的不断拓展中&#xff0c;用户渗透率提升&#xff0c;网络音频行业形成了多元化圈层。根据数据统计&#xff0c;网络音频行业在2021年用户规模就已达到6.4亿人&#xff0c;随着…