「C++ 类和对象篇 10」初始化列表

目录

一、什么是初始化列表?

二、为什么需要初始化列表?

三、初始化列表怎么使用?

3.1 在构造函数中使用初始化列表

3.2 注意

3.3 结论

3.4 应用场景

四、初始化列表的初始化顺序

五、另一种初始化成员变量的方法 

【总结】


一、什么是初始化列表?

       初始化列表是一种在构造函数初始化类成员变量的语法。初始化列表在构造函数体执行之前完成成员的初始化。

二、为什么需要初始化列表?

       之前使用构造函数初始化成员变量叫做函数体内初始化,它实际上是在成员变量创建后再给它赋值,所以它存在一些问题,如无法对引用类型的成员变量、const修饰的成员变量、类中没有默认构造函数的自定义类型进行初始化。


       在C++11前,定义成员变量时直接赋值是在构造函数体内进行的赋值操作,这相当于在给构造函数设置缺省值,而不是初始化成员变量。


       无论是定义成员变量时赋值(C++11前)还是使用构造函数,都不是在对成员变量进行初始化,这两种方式都只是在给成员变量赋值。关于这点我们可以使用g++编译器来检验:


        为解决引用等特殊成员变量的初始化问题,c++引入了初始化列表,如果类中包含以下成员,必须放在初始化列表位置进行初始化:

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

使用初始化列表的优点主要有:

  1. 性能:对于数据成员,使用初始化列表通常比在构造函数体内赋值更高效。因为赋值可能会涉及到对象的拷贝或移动,而使用初始化列表可以直接构造对象,避免额外的开销。

  2. 必要性:对于const或reference类型的成员变量,必须在初始化列表中初始化,因为它们不能在构造函数体内被重新赋值。

  3. 一致性:使用初始化列表可以确保所有成员变量在构造函数体执行前都已初始化,避免出现未定义行为。


三、初始化列表怎么使用?

3.1 在构造函数中使用初始化列表

        初始化列表只能用于构造函数中写在参数列表后,函数体前。以一个冒号开始,接着是一个以逗号分隔的数据成员列表。每个"成员变量"后面跟一个放在括号中的初始值或表达式。

class Student
{
private:string _name;const int _age;const string& _alias;
public:Student(string name):_name("lin"), _alias("L"), _age(18){_name = name;}
};

eg.列表初始化和函数体内赋值的对比:

3.2 注意

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

2. 类中包含以下成员,必须放在初始化列表位置进行初始化: 引用成员变量、const成员变量、没有默认构造函数的自定义类型成员。

class School{
private:string _name;
public:School(string name): _name("ECUT"){_name = name;}
};class Student{
private:const string _name;   //const成员const string& _alias; //引用成员School _sc;           //没有默认构造函数的自定义类型成员
public:Student():_name("lin"), _alias("L"),_sc(School("ECUT")){}
};

对于没有默认构造函数的自定义类型成员,必须使用初始化列表初始化,无法在构造函数中直接赋值:

3.3 应用场景

  • 形参名和成员变量名相同时,使用初始化列表可避免二义性问题。

  • 引用成员变量 、const成员变量 、没有默认构造函数的自定义类型成员。
  • 继承中子类的构造函数也必须初始化参数列表的方式。


四、初始化列表的初始化顺序

        成员变量初始化的顺序和变量在初始化列表中的顺序无关,和它们在类中定义的顺序有关即初始化列表按成员变量定义的顺序进行初始化。


        以下例子可以证明,初始化列表的初始化顺序只和成员变量在类中的定义顺序有关:

        如果初始化顺序和在初始化列表中的顺序有关,那么以上代码的结果应该为1 1。所以从以上结果可看出初始化列表的初始化顺序只和成员变量在类中的定义顺序有关,正因如此a先被初始化所以是随机值。


五、另一种初始化成员变量的方法 

         C++11后,支持在类定义中对非静态成员变量进行默认初始化。这种初始化方式被称为成员初始化器(Member Initializers)或默认成员初始化器(Default Member Initializers)。然而,需要注意的是,这种初始化方式并只适用于非静态成员。

        简单来说就是C++11后支持非静态成员在定义成员变量时进行初始化。

        这种方法虽然简便,但不推荐使用,因为这个特性是c++11后才支持的,在上图也可以看到必须让g++支持C++11后才能使用该方法初始化成员变量,也可以知道一些早期的项目并不兼容这种写法。 所以我们尽量使用初始化列表对成员变量进行初始化。


【总结】


------------------------END-------------------------

才疏学浅,谬误难免,欢迎各位批评指正。

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

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

相关文章

C++入门篇(4)—— 类与对象(1)

目录 1.类的引入 2.类的定义 3.类的访问限定符 4.类的作用域 5. 类对象的存储方式 6. this指针 6.1 this指针的引入 6.2 this指针的特性 6.3有意思的面试题 1.类的引入 C语言struct 结构体中只能定义变量,而C中可以定义函数。 struct Date {void Init(int…

vue常用9个事件修饰符

第075个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下,本专栏提供行之有效的源代码示例和信息点介绍,做到灵活运用。 提供vue2的一些基本操作:安装、引用,模板使用,computed&a…

vueRouter中Hash模式和History模式有什么区别

VueRouter是Vue.js官方推荐的前端路由库,它提供了一种方便的方式来构建单页应用(SPA)。在使用VueRouter时,我们可以选择不同的路由模式,其中最常见的是Hash模式和History模式。本文将深入探讨这两种模式的区别&#xf…

逐行拆解Guava限流器RateLimiter

逐行拆解Guava限流器RateLimiter 常见限流算法 计数器法 设置一个时间窗口内允许的最大请求量,如果当前窗口请求数超过这个设定数量,则拒绝该窗口内之后的请求。 关键词:时间窗口,计数器。 举个例子,我们设置1秒钟…

CSS3 基本语法

CSS3 基本语法 1. CSS3 新增长度单位 rem 根元素字体大小的倍数,只与根元素字体大小有关。vw 视口宽度的百分之多少 10vw 就是视口宽度的 10% 。vh 视口高度的百分之多少 10vh 就是视口高度的 10% 。vmax 视口宽高中大的那个的百分之多少。(了解即可&am…

JVM相关-JVM模型、垃圾回收、JVM调优

一、JVM模型 JVM内部体型划分 JVM的内部体系结构分为三部分,分别是:类加载器(ClassLoader)子系统、运行时数据区(内存)和执行引擎 1、类加载器 概念 每个JVM都有一个类加载器子系统(class l…

Spring Batch 批处理框架适配达梦数据库,实现从文件批量读取写入数据库(完整教程)

效果展示(达梦数据库): 技术简介: Spring Batch 是一个基于 Spring 的批处理框架,用于开发和执行大规模、高性能、可靠的批处理应用程序。它提供了丰富的功能和组件,用于处理复杂的批处理任务,例如大数据ETL(Extract-Transform-Load)、数据清洗、数据迁移、报表生成…

C# OCR识别图片中的文字

1、从NuGet里面安装Spire.OCR 2、安装之后,找到安装路径下,默认生成的packages文件夹,复制该文件夹路径下的 6 个dll文件到程序的根目录 3、调用读取方法 OcrScanner scanner new OcrScanner(); string path "C:\1.png"; scann…

React18原理: Fiber架构下的单线程CPU调度策略

概述 React 的 Fiber 架构, 它的整个设计思想就是去参考CPU的调度策略CPU现在都是多核多进程的,重点研究的是 CPU是单核单线程,它是如何调度的?为什么要去研究单线程的CPU? 浏览器中的JS它是单线程的JS 的执行线程和浏览器的渲染GUI 是互斥…

缺省参数(c++)

void fun(int a0) { cout<<a<<endl; } 当我们调用函数时: fun(10) 输出10; fun&#xff08;&#xff09; 未传参时&#xff1a; 输出0; 未传参时a就会接受0&#xff0c;相当于这个0就是“备胎” 传参了0就没有用 全缺省 void fun2(int a10,int b3,int…

为什么无法正常访问TikTok?该使用跨境专线吗?

TikTok作为全球范围内备受欢迎的社交媒体平台&#xff0c;吸引了数以亿计的用户。然而&#xff0c;有时候用户可能会遇到无法正常访问TikTok的问题&#xff0c;这可能涉及到多方面的因素。本文将深入探讨为什么可能无法正常访问TikTok&#xff0c;并考虑是否使用 TikTok跨境专线…

使用vue-client-only 解决组件不兼容SSR问题

目录 前言 一、解决方案 1.基于Nuxt 框架的SSR应用 2.基于vue2框架的应用 3.基于vue3框架的应用 二、总结 往期回顾 前言 最近在我的单页面SSR应用上开发JSON编辑器功能&#xff0c;在引入组件后直接客户端跳转OK&#xff0c;但是在直接加载服务端渲染的时候一直报这…

ADMap:Anti-disturbance framework for reconstructing online vectorized HD map

参考代码&#xff1a;ADMap 动机与出发点 局部地图构建算法在实际中会遇到部分车道线偏离的或是错误的情况&#xff0c;这往往是全局信息获取上存在欠缺&#xff0c;毕竟地图元素的回归很依赖于全局信息的获取。那么从特征提取、attention layer设计和loss构建上可以做一些工作…

visual studio和cmake如何编译dlib库

官网 dlib C Library 对应的是最新版本&#xff0c;只能用到vs2015版本及以后 如果使用vs2013&#xff0c;所以需要下载vs2013可用的版本。 就是说dlib版本与vs版本有对应关系 所有版本 dlib C Library - Browse /dlib at SourceForge.net Releases davisking/dlib GitHu…

Go语言每日一练——链表篇(八)

传送门 牛客面试笔试必刷101题 ----------------两个链表的第一个公共结点 题目以及解析 题目 解题代码及解析 解析 这一道题使用的还是双指针算法&#xff0c;我们先求出两个链表的长度差n&#xff0c;然后定义快慢指针&#xff0c;让快指针先走n步&#xff0c;最后快慢指…

【数学建模】【2024年】【第40届】【MCM/ICM】【B题 搜寻潜水器】【解题思路】

一、题目 &#xff08;一&#xff09;赛题原文 2024 MCM Problem A: Resource Availability and Sex Ratios Maritime Cruises Mini-Submarines (MCMS), a company based in Greece, builds submersibles capable of carrying humans to the deepest parts of the ocean. A …

app逆向-⽹络请求库okhttp3

文章目录 一、前言二、应用1、添加权限AndroidManifest.xml2、添加依赖okhttp33、编写界面文件activity_main.xml4、编写Activity代码 三、效果 一、前言 OkHttp是由Square公司开发的用于Java和Android的开源HTTP客户端库。它被广泛用于在Java和Android应用程序中进行HTTP请求…

结构体数组所有元素(1亿个元素)初始化为相同的值

一个结构体数组&#xff0c;有1亿个元素&#xff0c;每个元素都要初始化为相同的值&#xff0c;如果没有现成的语法直接支持这样的初始化操作&#xff0c;就得用for循环写&#xff0c;会不会非常耗时&#xff1f; 如果结构体里的成员都是一些简单的基本数据类型&#xff0c;整…

小游戏和GUI编程(5) | SVG图像格式简介

小游戏和GUI编程(5) | SVG图像格式简介 0. 问题 Q1: SVG 是什么的缩写&#xff1f;Q2: SVG 是一种图像格式吗&#xff1f;Q3: SVG 相对于其他图像格式的优点和缺点是什么&#xff1f;Q4: 哪些工具可以查看 SVG 图像&#xff1f;Q5: SVG 图像格式的规范是怎样的&#xff1f;Q6…

Linux中常用的工具

软件安装 yum 软件包 在Linux中&#xff0c;软件包是一种预编译的程序集合&#xff0c;通常包含了用户需要的应用程序、库、文档和其他依赖项。 软件包管理工具是用于安装、更新和删除这些软件包的软件。常见的Linux软件包管理工具包括APT&#xff08;Advanced Packaging To…