初始化列表的特性和构造函数的工作原理

2023-10-26

对于构造函数我们一直有个误区,就是构造函数用于初始化成员变量创建对象,实际上并不是这样的。真正的初始化并不是在构造函数中完成的,而是在初始化列表中完成的,构造函数中的实际上是赋值操作。

要了解构造函数的工作原理,得先了解什么是初始化列表

初始化列表: 以一个冒号开始,接着是一个以逗号分隔的成员变量列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式。初始化列表才是成员变量初始化定义的地方,也就是为其开辟空间的地方。

具体我们来看下面代码,我们有一个日期类对象,我们可以这样来定义构造函数:

class Date                                                                                                                                                   
{                                                                                                                                                            
  public:                                                                                                                                                    
    Date(int year,int month,int day)                                                                                                                         
    {                                                                                                                                                        
      _year = year;                                                                                                                                          
      _month = month;                                                                                                                                        
      _day = day;                                                                                                                                            
    }                                                                                                                                                        
  protected:                                                                                                                                                 
    int _year;                                                                                                                                               
    int _month;                                                                                                                                              
    int _day;                                                                                                                                                
};         

也可以利用初始化列表:

class Date                                                                                                                                                   
{                                                                                                                                                            
  public:       
    //使用初始话列表初始化成员变量                                                                                                                                               
    Date(int year,int month,int day):_year(year), _month(month), _day(day){}                                                                                                                                                                                                                                                                                                                                                                         
  protected:                                                                                                                                                 
    int _year;                                                                                                                                               
    int _month;                                                                                                                                              
    int _day;                                                                                                                                                
};         

了解了什么是初始化列表之后,继续学习初始化列表的特性,但是学完后你就会发现初始化列表的特性其实就是构造函数的工作原理。

初始化列表的特性/构造函数的工作原理:

  1. 所有构造函数都要先走初始化列表再走函数体,初始化列表会给每个成员都进行一次初始化,如果你的初始化列表显示初始化了某个成员,它就会去初始化,如果你没有显式初始化某个成员,它也会初始化,对于基本类型的成员变量,它会按照默认值进行初始化,如果没有设置默认值,就会用随机值进行初始化,对于自定义类型成员会调用它的默认构造函数进行初始化,如果该自定义类型的成员变量没有默认构造函数,则编译器调用构造函数创建对象的时候就会报错,因为当你没有在构造函数的初始化化列表中对自定义类型成员进行显示初始化的时候,编译器会调用自定义类型成员的默认构造函数在初始化列表中来对其进行初始化,而自定义类型的成员变量没有默认构造函数,所以会报错,所以我们需要在初始化列表中对没有默认构造函数的自定义类型成员变量进行显式初始化,即显示调用该自定义类型成员变量的其它构造函数。

    也就是说尽管你在构造函数体内进行“初始化”操作,实际上人家已经在初始化列表中就初始化过了,你在构造函数体内的“初始化”操作实际上只是二次赋值操作,所以还不如在初始化列表中直接进行初始化操作。

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

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

    • 引用成员变量,引用必须在定义的时候就进行初始化,如果你不在初始化列表中对引用进行显示初始化,初始化列表就会用默认值或者用引用成员变量所在空间的脏值(随机值)对其进行初始化,由于引用不能被重新赋值,后面我们就无法在构造函数中将引用赋值为我们想要的值了,所以引用成员变量一定要写在初始化列表里面进行显式初始化。
    • const成员变量,原因同引用(const变量必须在定义的时候就进行初始化,且不能被重新赋值)
  4. 成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关

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();
}
A.输出1 1
B.程序崩溃
C.编译不通过
D.输出1 随机值//选D

何时使用编译器自动生成的无参默认构造函数就够了,何时需要自己实现构造函数呢?

如果一个类中的成员全是自定义类型,或者基本类型成员在声明时已经给了缺省值,即无需对基本类型成员变量做处理,且自定义成员都提供了默认构造函数,此时使用编译器自动生成的无参默认构造函数就可以了。

如果有基本类型的成员变量且需要显示传参初始化,即我们需要自己对基本类型成员变量进行处理,或者自定义类型成员没有默认构造函数,那么就要自己实现构造函数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

初始化列表的特性和构造函数的工作原理 的相关文章

随机推荐

  • 五、单向散列函数

    单向散列函数 获取消息的指纹 当需要比较两条消息是否一致时 我们不必直接对比消息本身的内容 只要对比它们的 指纹 就可以了 单向散列函数 one wayftnction 有一个输人和一个输出 其中输人称为消息 message 输出称为散列值
  • 全国大学生数字建模竞赛、中国研究生数学建模竞赛(数学建模与计算实验)前言

    1 什么是数学建模 2 所需要学的知识 知识算法分类表格汇总 3 所需要的软件工具 4 论文模板 查找文献 查找数据 一 什么是数学建模 全国大学生数字建模竞赛 National College Student Mathematical M
  • HashMap源码初探

    Hash table based implementation of the Map interface This implementation provides all of the optional map operations and
  • Qt动态库加载之 QLibrary

    目录 一 使用Qt编译C动态库 二 使用QLibrary调用共享库 一 使用Qt编译C动态库 使用Qt新建一个C项目 cbb frame 在项目中我们声明和定义两个函数 并导出函数 在cbb mylog中我们使用了函数指针 这里为啥这样干
  • python人脸识别考勤系统 dlib+OpenCV和Pyqt5、数据库sqlite 人脸识别系统 计算机 毕业设计 源码

    一 项目介绍 Python语言 dlib OpenCV Pyqt5界面设计 sqlite3数据库 本系统使用dlib作为人脸识别工具 dlib提供一个方法可将人脸图片数据映射到128维度的空间向量 如果两张图片来源于同一个人 那么两个图片所
  • hrformer

    High Resolution Transformer Copyright c 2021 Microsoft Licensed under The MIT License see LICENSE for details Written by
  • keepalived 实现双机热备

    文章目录 一 说明 二 概念解释 三 环境准备 四 操作过程 五 验证 一 说明 我们经常听说 nginx keepalived 双机热备 其实在这里 双机热备有两种思路 一是只利用 keepalived 实现两个节点的故障切换 当主节点挂
  • 章节二:Vue.js的安装和配置

    2 1 下载和安装Vue js 要下载和安装Vue js 你有几个选项可供选择 通过CDN 在HTML文件中引入Vue js的CDN链接 然后直接使用Vue全局变量 使用包管理器 使用npm或yarn等包管理器 在项目中安装Vue js 下
  • 一文搞懂IP基础以及子网划分!!!!!

    1 什么是IP地址 IP地址 Internet Protocol Address 互联网国际地址 是一种在Internet上的给主机编址的方式 它主要是为互联网上的每一个网络和每一台主机分配一个逻辑地址 以此来屏蔽物理地址的差异 IP地址就
  • Reactjs鼠标滚轮监听

    1 添加相应的react所需的包及插件 npm install react s npm install react dom s 2 鼠标滚轮事件及引用子组件的滚轮处理事件 handleWheel function event 判断鼠标滚轮的
  • JavaBean配置

    在JSP内嵌入大量的Java代码可能会造成维护不方便 为此最好的方就是把JSP代码和Java代码分开 将JSP中的Java代码移植到Java类中 这些可能用到的类就是JavaBean JavaBean实现步骤如下 1 在src中新建一个be
  • 微型计算机上的南桥芯片功能,微型计算机主板上安装的主要部件

    如下 1 芯片组 芯片组是构成主板电路的核心 决定了主板的级别和档次 北桥芯片是主板上最重要的芯片 主要负责与CPU 内存 显卡进行通讯 南桥芯片负责连接硬盘 USB 接口 PCI 接口等其他接口 南桥芯片和北桥芯片之间也有联系 2 存储控
  • 洋桃电子STM32物联网入门30步笔记三、CubeMX图形化编程、设置开发板上的IO口

    此文档作为对杨桃电子视频的整理 B站链接 第四集 一 开启RCC的外部时钟 包括外部高速时钟HSE和外部低速时钟LSE 时钟配置三个选项的含义 选择禁用的话就只能使用内部时钟 旁路时钟源一般是有源晶振 晶体与陶瓷振荡器一般是无源晶振 二 开
  • 利用JS获取IE客户端IP及MAC的实现

    在做B S结构的系统时 我们常常需要获取客户端的一些信息 如IP和MAC 以结合身份验证 在ASP NET中 要获取服务器端的MAC很容易 但是要获取客户端的MAC的地址确要花费一翻心思 通常的做法是调用Win32API或直接调用nbtst
  • MySQL技术内幕InnoDB存储引擎 学习笔记 第六章 锁

    锁是数据库系统区别于文件系统的一个关键特性 锁机制用于管理对共享资源的并发访问 InnoDB引擎会对表数据上锁以提供数据的完整性和一致性 除此之外 还会对数据库内部其他多个地方使用锁 从而保证对多种不同资源提供并发访问 如增删改LRU列表中
  • 基于Centos7+pycharm搭建python获取爬虫小项目

    一 安装python环境 网上教程查阅 安装成功后运行 python 查看版本 python V 二 安装pycharm 应在步骤一完成后进行 到pycharm官网下载最新版本 下载链接 https www jetbrains com py
  • 详解 Springboot 中使用 Aop

    一 什么是 Aop AOP Aspect Oriented Programming 意为面向切面编程 可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术 AOP的编程思想是把对类对象的横切问题点 从
  • CentOS 修改时间

    Centos系统时间分为系统时间和硬件时间 二者必须都修改 重启系统才会永久生效 查询时间常用命令 date date R date z hwclock r 一 修改时区 修改时区 ln sf usr share zoneinfo Asia
  • XMind思维导图的结构逻辑该如何体现?3个功能完美体现!

    假设你在玩 模拟城市 但你必须使用以下工具来构建城市 中心主题 城市中心 关键思想 主要道路 次要的思想 次要的道路 标志 地标图片 那么你要怎么安排才能让城市结构附有逻辑性 让城市的规划更加合理 这就是我们将要讨论的问题 同样在我们的思维
  • 初始化列表的特性和构造函数的工作原理

    对于构造函数我们一直有个误区 就是构造函数用于初始化成员变量创建对象 实际上并不是这样的 真正的初始化并不是在构造函数中完成的 而是在初始化列表中完成的 构造函数中的实际上是赋值操作 要了解构造函数的工作原理 得先了解什么是初始化列表 初始