「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.hqwc.cn/news/464919.html

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

相关文章

快速幂的应用

1.非递归的解法 #include <iostream> using namespace std; int main(){int a,b,c,t1;cin>>a>>b>>c;if(a>2&&a<1e3&&b>0&&a<1e7&&c>2&&c<1e5)for(int i0;i<b;i)tt*a%c;cout<<t;r…

51单片机编程应用(C语言):篮球比赛计分器

设计思路 1.LCD1602显示A 000:B 000 右下角显示24的数字&#xff0c;显示一节时间12&#xff1a;00. 2.规定矩阵键盘每一位表示的含义 s1按下&#xff0c;A队加一分 s2按下&#xff0c;A队加两分 s3按下&#xff0c;A队加三分 s4按下&#xff0c;A队减一分 如…

[数学]高斯消元

介绍 用处&#xff1a;求解线性方程组 加减消元法和代入消元法 这里引用了高斯消元解线性方程组----C实现_c用高斯消元法解线性方程组-CSDN博客 改成了自己常用的形式&#xff1a; int gauss() {int c, r; // column, rowfor (c 1, r 1; c < n; c ){int maxx r; //…

【开源】JAVA+Vue.js实现衣物搭配系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 衣物档案模块2.2 衣物搭配模块2.3 衣物收藏模块 三、系统设计3.1 用例设计3.2 E-R图设计3.3 数据库设计3.3.1 衣物档案表3.3.2 衣物搭配表3.3.3 衣物收藏表 四、系统实现4.1 登录页4.2 衣物档案模块4.3 衣物搭配模块4.4…

奶茶点餐|奶茶店自助点餐系统|基于微信小程序的饮品点单系统的设计与实现(源码+数据库+文档)

奶茶店自助点餐系统目录 目录 基于微信小程序的饮品点单系统的设计与实现 一、前言 二、系统功能设计 三、系统实现 1、商品信息管理 2、商品评价管理 3、商品订单管理 4、用户管理 四、数据库设计 1、实体ER图 2、具体的表设计如下所示&#xff1a; 五、核心代码 …

【深度学习:语义分割】语义分割简介

【深度学习&#xff1a;语义分割】语义分割简介 什么是图像分割&#xff1f;了解语义分割数据采集语义分割的深度学习实现全卷积网络上采样跳跃连接U-NetDeepLab多尺度物体检测金字塔场景解析网络&#xff08;PSPNet&#xff09; 语义分割的应用医学影像自动驾驶汽车农业图片处…

MongoDB从入门到实战之.NET Core使用MongoDB开发ToDoList系统(1)-后端项目框架搭建

前言&#xff1a; 前面的四个章节我们主要讲解了MongoDB的相关基础知识&#xff0c;接下来我们就开始进入使用.NET7操作MongoDB开发一个ToDoList系统实战教程。本章节主要介绍的是如何快熟搭建一个简单明了的后端项目框架。 MongoDB从入门到实战的相关教程 MongoDB从入门到实战…

华为OD机试 - 分配土地( Python C C++ JavaGo JS PHP)

题目描述 从前有个村庄&#xff0c;村民们在各种田地上插上小旗子&#xff0c;每个旗子上都标识了一个数字。现在&#xff0c;村民们想要找出一个包含相同数字的最小矩形区域&#xff0c;并将这块土地分配给对村庄做出巨大贡献的村民。我们需要找出这个矩形区域的最大面积。 …

js基础(2)

对象 object也是js的一种数据类型 其静态特征可以用基本数据类型表示 动态行为可以用函数表示 语法&#xff1a; 增删改查 查&#xff1a;对象.属性 改: 对象.属性值 增&#xff1a;对象.新属性名新值 删&#xff1a;delete 对象.属性名 查的另一种写法&#xff1a; 对…

算法学习——LeetCode力扣双指针篇

算法学习——LeetCode力扣双指针篇1 27. 移除元素 27. 移除元素 - 力扣&#xff08;LeetCode&#xff09; 描述 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#…

MongoDB存储引擎发展及WiredTiger深入解析(二)

在现代的数据管理领域中&#xff0c;MongoDB作为一个高性能、开源的NoSQL数据库系统&#xff0c;已经在全球范围内被广泛应用。而MongoDB背后的存储引擎&#xff0c;作为其数据管理的核心组件&#xff0c;也经历了不断的发展和优化。本文将对MongoDB的存储引擎发展进行简要回顾…

算法搜索(2024/2/5)

搜索 目录 搜索 深度优先搜索 广度优先搜索 &#xff08;宽度优先搜索&#xff09; 今日刷题 p1387 最大正方形 题目描述 输入格式 输出格式 输入输出样例 1、定义&#xff1a; 搜索是一种通过穷举所以可能的解的状态&#xff0c;来求得题目所需求的解或最优解…