C++-再探构造函数(进阶)

news2024/11/20 15:39:10

 个人主页:Jason_from_China-CSDN博客

所属栏目:C++系统性学习_Jason_from_China的博客-CSDN博客

所属栏目:C++知识点的补充_Jason_from_China的博客-CSDN博客

前言

 来到类和对象最后一个章节,这里的难度已经极大程度的降低了 

再探构造函数

概念概述

  • 之前我们实现构造函数时,初始化成员变量主要使用函数体内赋值,构造函数初始化还有一种方式,就是初始化列表,初始化列表的使用方式是以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个 “成员变量” 后面跟一个放在括号中的初始值或表达式。
  • 每个成员变量在初始化列表中只能出现一次,语法理解上初始化列表可以认为是每个成员变量定义初始化的地方。
  • 引用成员变量,const 成员变量,没有默认构造的类类型变量,必须放在初始化列表位置进行初始化,否则会编译报错。
  • C++11 支持在成员变量声明的位置给缺省值,这个缺省值主要是给没有显示在初始化列表初始化的成员使用的。
  • 尽量使用初始化列表初始化,因为那些你不在初始化列表初始化的成员也会走初始化列表,如果这个成员在声明位置给了缺省值,初始化列表会用这个缺省值初始化。如果你没有给缺省值,对于没有显示在初始化列表初始化的内置类型成员是否初始化取决于编译器,C++ 并没有规定。对于没有显示在初始化列表初始化的自定义类型成员会调用这个成员类型的默认构造函数,如果没有默认构造会编译错误。
  • 初始化列表中按照成员变量在类中声明顺序进行初始化,跟成员在初始化列表出现的的先后顺序无关。建议声明顺序和初始化列表顺序保持一致。
  • 初始化列表总结:无论是否显式写初始化列表,每个构造函数都有初始化列表;无论是否在初始化列表显示初始化,每个成员变量都要走初始化列表初始化。

成员变量初始化列表逻辑

再探构造函数存在的意义

//比如我们写一个栈,这里就不需要写构造函数,因为编译器默认生成队列的构造函数调用了stack的默认构造,完成了两个成员函数的初始化

//但是如果栈的默认构造是没有的情况下,此时怎么处理?所以就需要延伸到再探构造函数

初始化列表的格式

之前我们进行初始化是函数体的初始化,现在称之为初始化列表的初始化

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

使用的格式记住就可以

哪些成员必须采用初始化列表(没有默认构造函数的,需要使用初始化列表

//构造函数
Date(int year = 1901, int month = 1, int day = 1);

构造函数
//Date::Date(int year, int month, int day)
//{
//	_year = year;
//	_month = month;
//	_day = day;
//}
//构造函数,初始化列表的实现
Date::Date(int year, int month, int day)
	:_year(111)
	, _month(111)
	, _day(111)
{}
int main() {
    // 明确传递参数,使用带参数的构造函数和初始化列表进行初始化
    Date d1(2024, 9, 27); 

    // 不传递参数,使用默认参数值和初始化列表进行初始化
    Date d2; 

    return 0;
}
//不是单纯地调用默认构造函数,而是根据是否传递参数来决定使用带参数的构造函数(带默认参数),并且始终会使用初始化列表进行初始化。

//如果传递参数调用构造函数,如Date d1(2024, 9, 27);,会优先使用初始化列表,按照给定的参数值初始化成员变量_year、_month和_day。
//如果不传递参数,如Date d2;,则会使用构造函数中的缺省参数值,并同样通过初始化列表来初始化成员变量。

哪些成员必须采用初始化列表(const修饰的成员变成必须使用初始化列表)

一,const 成员函数的特性

const 成员函数承诺不修改对象的数据成员,即它保证了在函数执行期间,对象的状态不会被改变。这意味着 const 成员函数应该只能读取对象的状态,而不能进行任何可能改变对象状态的操作。

二,函数体初始化与初始化列表的区别

  1. 函数体初始化:在函数体内部进行成员变量的初始化是通过赋值操作来完成的。这意味着先调用默认构造函数(如果有)创建成员变量,然后再对其进行赋值。这种方式可能会导致对象被临时创建和赋值两次,增加了不必要的开销,并且在一些情况下可能违反 const 成员函数的不修改对象状态的承诺。
  2. 初始化列表:初始化列表在对象创建时直接初始化成员变量,避免了先调用默认构造函数再赋值的过程对于 const 成员变量和引用成员变量,必须在初始化列表中进行初始化,因为它们不能在创建后被重新赋值。对于普通成员变量,使用初始化列表也可以提高效率,并且更符合 C++ 的初始化语义。

代码实现:这里主要看成员变量_y

#include<iostream>
using namespace std;
class Date
{
public:
	Date(int& z);
	Date(int x,  int& z);
	Date(int x, int y, int& z);
	void _print()
	{
		cout << _x << "/" << _y << "/" << _z << endl << endl;
	}
private:
	int _x;
	const int _y;
	int& _z;
};
//再探构造函数1
Date::Date(int& z)
	:_x(111)
	, _y(111)
	, _z(z)
{}
//再探构造函数2
Date::Date(int x, int& z)
	:_x(222)
	, _y(222)
	, _z(z)
{}
//再探构造函数3
Date::Date(int x, int y, int& z)
	: _y(333)
	,_z(z)
{
	_x = x;
}

int main()
{
	//再探构造函数1
	int i1 = 0;
	Date d1(i1);
	d1._print();
	cout << i1 << endl << endl;

	//再探构造函数2
	int i2 = 0;
	Date d2(1, i1);
	d2._print();
	cout << i2 << endl << endl;

	//再探构造函数3
	int i3= 0;
	Date d3(1, 1, i3);
	d3._print();
	cout << i3 << endl;
	return 0;
}

哪些成员必须采用初始化列表(引用成员变量的初始化)

一、引用的特性

 

引用在 C++ 中必须在定义时被初始化,并且一旦初始化后就不能再绑定到其他对象。引用本质上是一个对象的别名,它总是指向一个特定的对象,不能被重新赋值为指向另一个不同的对象。

 

二、构造函数的执行过程

 
  1. 当一个对象被创建时,构造函数首先执行初始化列表来初始化成员变量。如果不在初始化列表中初始化引用成员变量,那么在构造函数体中就没有机会再对其进行初始化了,因为此时引用必须已经被绑定到一个对象。
  2. 如果试图在构造函数体中对引用成员变量进行赋值,这会被编译器视为重新绑定引用,而这是不允许的,会导致编译错误。

三、左值和右值的概念

  • 左值(lvalue):代表一个有明确内存地址、可以取地址且有可持久性的值。通常可以出现在赋值语句的左侧,例如变量名、解引用的指针等。例如,int a = 10;中的a就是一个左值,因为它有明确的内存地址,可以通过&a取地址,并且在程序的生命周期内持续存在。引用成员变量的初始化就是不修改的左值。
  • 右值(rvalue):通常是临时的值,没有明确的内存地址可获取,或者是即将被销毁的值。例如,字面常量、临时对象、函数返回的临时值等。例如,int b = 15 + 20;这里15 + 20的结果就是一个右值,它是一个临时值,没有独立的内存地址可获取,在表达式结束后可能就会被销毁。

代码实现

#include<iostream>
using namespace std;
class Date
{
public:
	Date(int& z);
	Date(int x,  int& z);
	Date(int x, int y, int& z);
	void _print()
	{
		cout << _x << "/" << _y << "/" << _z << endl << endl;
	}
private:
	int _x;
	const int _y;
	int& _z;
};
//再探构造函数1
Date::Date(int& z)
	:_x(111)
	, _y(111)
	, _z(z)
{}
//再探构造函数2
Date::Date(int x, int& z)
	:_x(222)
	, _y(222)
	, _z(z)
{}
//再探构造函数3
Date::Date(int x, int y, int& z)
	: _y(333)
	,_z(z)
{
	_x = x;
}

int main()
{
	//再探构造函数1
	int i1 = 0;
	Date d1(i1);
	d1._print();
	cout << i1 << endl << endl;

	//再探构造函数2
	int i2 = 0;
	Date d2(1, i1);
	d2._print();
	cout << i2 << endl << endl;

	//再探构造函数3
	int i3= 0;
	Date d3(1, 1, i3);
	d3._print();
	cout << i3 << endl;
	return 0;
}

初始化列表的注意事项(初始化的顺序)

初始化列表的注意事项(尽量都使用初始化列表进行初始化)

这里建议尽量使用初始化列表进行初始化,因为在C++里面,他是有一套构造流程的,而且对于C++来讲,为什么比其他语言快,不仅仅的这个语言本身的特点,还是在书写的时候,我们会更加注意程序的设计

初始化列表的注意事项(建议声明和顺序保持一致)

这里也是一个需要注意的点

因为编译器进行初始化的时候,是按照头文件进行初始化的,不是你实现的顺序来进行初始化的

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

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

相关文章

FFMpeg源码分析,关键结构体分析(一)

http://lazybing.github.io/blog/categories/ffmpegyuan-ma-fen-xi/ 一、下载FFmpeg的编译源码 进入网站&#xff1a;http://ffmpeg.org/download.html二、编译源码 执行下述命令&#xff1a; ./configure --prefix/usr/local/ffmpeg --enable-debug3 --enable-ffplay sudo …

22年408数据结构

第一题&#xff1a; 解析&#xff1a; 观察一下这个程序&#xff1a;我们注意到最外层的循环是从i1开始的&#xff0c;每次ii*2&#xff0c;直到i<n为止&#xff0c;假设程序总共执行k次执行&#xff0c;则有2^(k1)>n。则k1>log(2)n这里是以2为底n的对数, k>log(2)…

Oracle11g服务器linux 安装

一&#xff0e;安装前准备 1.检查硬件&#xff08;内存&#xff0c;交换分区&#xff0c;tmp分区&#xff0c;cpu信息&#xff0c;内核版本&#xff09; # grep MemTotal /proc/meminfo # grep SwapTotal /proc/meminfo # df -k /tmp&#xff08;>400M&#xff09; # grep …

汽车氛围灯行业分析:未来几年年复合增长率CAGR为7.15%

汽车氛围灯是一种起到装饰和指示作用的照明灯&#xff0c;它属于装饰类的照明灯。通常是红色、蓝色、绿色等&#xff0c;主要是为了使车厢更加绚丽&#xff0c;烘托气氛&#xff0c;营造室内情调。氛围灯能够具有以下特性&#xff1a;功能性、舒适性、设计感、豪华感、个性化、…

【C++】——继承

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件stdio.h的声明&#xff0c;使用时请自行添加。 博主主页&#xff1a;Yan. yan.                        …

深入解析MySQL事务管理:ACID特性与基本操作

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storm…

自动猫砂盆是养猫新型智商税吗?测评2024年热门款智能猫砂盆分享

铲屎官们只要一察觉到猫主子拉屎&#xff0c;就要马上去铲掉&#xff0c;这不仅是为了猫砂盆中其他干净的猫砂&#xff0c;更是为了防止猫屎残留发臭&#xff0c;特别是便便这种东西&#xff0c;一旦放久了就很招虫子&#xff0c;家里出现这些虫子又要大扫除消杀&#xff0c;特…

2024 年顶级智能文档处理解决方案

在当今的数字时代&#xff0c;智能文档处理(IDP) 对于提高业务效率和降低成本至关重要。IDP 可实现文档处理的自动化&#xff0c;最大限度地减少人工劳动和错误。由于有众多 IDP 解决方案可供选择&#xff0c;因此选择合适的解决方案可能具有挑战性。 本指南回顾了 10 款最…

Android Handler消息机制完全解析-同步屏障(三)

Android 消息机制Handler完全解析(一) Android 消息机制Handler完全解析(二) 前面两篇我们主要讲了Handler消息机制的一些基础&#xff0c;今天来看下消息屏障&#xff0c;通过本篇文章你将学到如下知识点 (1)什么是同步屏障 (2)为什么要有同步屏障 (3)同步屏障的原理 (4…

获取时隔半个钟的三天

摘要&#xff1a; 今天遇到需求是配送时间&#xff0c;时隔半个钟的排线&#xff01;所以需要拼接时间&#xff01;例如2024-10-08 14&#xff1a;30&#xff0c;2024-10-08 15&#xff1a;00&#xff0c;2024-10-08 15&#xff1a;30 <el-form-item label"配送时间&a…

24下软考中级系统集成项目管理工程师怎么备考?

备考资料&#xff1a; 1.教材 教材可以准备由清华大学出版社出版的系统集成项目管理工程师教材&#xff0c;这也是官方所推荐的教材&#xff0c;准备这本书是绝对没错的。 2.真题 真题也是在备考过程中少不了的资料之一&#xff0c;而且系统集成项目管理工程师考试就是需要多…

初始项目托管到gitee教程,开箱即用

0.本地仓库与远程仓库关联&#xff08;需先在gitee创建仓库&#xff09; ①打开powershell生成ssh key ssh-keygen -t ed25519 -C "Gitee SSH Key"-t key 类型-C 注释 生成成功如下&#xff0c;并按下三次回车 ②查看公私钥文件 ls ~/.ssh/输出&#xff1a; id_…

华为---Super VLAN简介及示例配置

目录 1. Super VLAN技术产生背景 2. Super VLAN概念 3. Super VLAN应用场景 4. Super VLAN工作原理 5. Super-VLAN主要配置命令 6. Super-VLAN主要配置步骤 7. 示例配置 7.1 示例场景 7.2 网络拓扑 7.3 配置代码 7.4 代码解析 7.5 测试验证 1. Super VLAN技术产生背…

虹软人脸 报错 Can‘t find dependent libraries

系列文章目录 文章目录 系列文章目录一、虹软人脸 报错 Can‘t find dependent libraries 一、虹软人脸 报错 Can‘t find dependent libraries 在项目中使用了 虹软 人脸识别SDK&#xff0c;环境一直出错。 错误&#xff1a; Can’t find dependent libraries 从错误信息来…

项目启动 | 盘古信息赋能奥尼视讯数字化转型升级,实现全面数智化发展

随着信息技术的飞速发展与全球市场竞争的日益激烈&#xff0c;传统制造业正面临生存和发展的危机&#xff0c;制造企业为谋求发展&#xff0c;纷纷开启数字化转型之路&#xff0c;深度融入数字技术&#xff0c;实现生产流程的智能化、管理模式的精细化以及产品服务的个性化&…

[面试] java开发面经-1

前言 目录 1.看到你的简历里说使用Redis缓存高频数据&#xff0c;说一下Redis的操作 2.说一下Redis的缓存击穿、缓存穿透、缓存雪崩 3.你的项目中使用了ThreadLocal&#xff0c;那么当有两个请求同时发出时&#xff0c;会怎么处理&#xff0c;可以同时处理两个请求吗 4.使用…

CUDA、Pytorch、Pycharm的安装与配置

文章目录 一、CUDA安装1.检查英伟达驱动支持的最高CUDA版本 二、Pytorch的安装与环境配置1.选择是下载CPU版本还是GPU版本2.上Pytorch官网找到安装命令3.运行指令(1)CPU版本(2)GPU版本 4.验证5.安装其他所需模块(0)安装torch(1)安装Matplotlib(2)安装 pillow&#xff08;可能an…

高效稳压,YB2411 DCDC降压芯片助力高电压功率转换系统

在现代的科技发展中&#xff0c;高电压功率转换系统的需求越来越多。为满足市场需求&#xff0c;我们推出了一款高输入电压DCDC降压芯片——YB2411。 YB2411系列 1>昱灿 YB2411R SOT23-6 DC-DC高压降压 36V 0.6A 2>昱灿 YB2411SR SOT23-6 DC-DC高压降压 60V 0.8A YB241…

【simulink仿真模型】Buck变换器闭环控制,电力电子仿真模型

摘要 本文介绍了基于Simulink的Buck变换器闭环控制系统的设计与仿真。通过对Buck变换器的数学模型进行建模&#xff0c;并引入PI控制器对输出电压进行实时调节&#xff0c;实现了系统的稳态控制。仿真结果显示&#xff0c;该闭环控制系统能够快速响应负载变化&#xff0c;保持…

头戴式耳机性价比推荐有哪些?头戴式耳机性价比之王推荐

这不是马上就要双十一了&#xff1f;对于环境比较吵的人来说&#xff0c;趁着最近双11开始&#xff0c;是购买耳机的好时机。即将入冬&#xff0c;佩戴头戴式耳机频率越来越多&#xff0c;包裹着耳朵很舒适保暖。有的人入耳式已经非常多了&#xff0c;而且同样的价格&#xff0…