我与C++的爱恋:隐式类型转换

news2024/11/18 22:41:24


外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

🔥个人主页guoguoqiang. 🔥专栏我与C++的爱恋

Alt

朋友们大家好,本篇内容我们来介绍初始化列表,隐式类型转换以及explicit的内容

一、初始化列表

1.1 构造函数体赋值

在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值

class Date { public: Date(int year, int month, int day) { _year = year; _month = month; _day = day; } private: int _year; int _month; int _day; };
​虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称为对对象中成员变量的初始化,构造函数体中的语句只能将其称为赋初值,而不能称作初始化。因为初始化只能初始化一次,而构造函数体内可以多次赋值。

1.2 初始化列表

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

class Date
{
public:
	Date(int year=1900, int month=2, int day=2){
		_n = 10;
		_year = year;
		_month = month;
		_day = day;
}
private:
	int _year;
	int _month;
	int _day;
	const int _n;
};

在这里插入图片描述
我们发现const成员变量并不能用函数体进行初始化
int _year;
int _month;
int _day;
这三个成员既可以在函数体,又可以在初始化列表。
但是类中有的成员必须放在初始化列表位置进行初始化:
1.const 成员变量
2.引用成员变量
3.自定义类型成员(且没有默认构造函数)

int _year;
int _month;
int _day;
const int _n;

这个是声明,定义是对象实例化的时候完成的,有些成员必须在定义的时候初始化。

class Date
{
public:
	Date(int year, int month, int day)
		:_n(1)
		,_year (year)
		,_month(month)
		,_day (day)
	{}
private:
	int _year;
	int _month;
	int _day;
	const int _n;
};

初始化列表是每个成员变量定义初始化的地方

class Date2 {
public:
	Date2(int year, int month, int day)	
		:_n(1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;
	const int _n;
};

不管你写不写每个成员都要走初始化列表。没有在初始化列表中显式初始化_year、_month、和_day这三个成员变量,它们仍然会在初始化列表阶段被默认初始化,然后在构造函数体内被赋新的值
所有的成员,你可以在初始化列表初始化,也可以在函数体内部初始化。

我们之前也说到过缺省值,声明时给初始值。

private:
	int _year=2024;
	int _month;
	int _day;
	const int _n;

缺省值的本质是给初始化列表。
在这里插入图片描述

尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化。
引用类型必须在定义的时候初始化,所以也得使用初始化列表

class A {
public:
	A(int a = 0)
		: _a(a)
	{}
private:
	int _a;
};
class Date
{
public:
	Date(int year, int month, int day)
		:_n(1)
		, _year(year)
		, _month(month)
		, _day(day)
		, _ref(x)
	{}
private:
	int _year=1;
	int _month;
	int _day;
	const int _n;
	int& _ref;
	A aa;
};
int main() {
	Date d2(2024, 4, 20);
	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();
}

这个结果是什么呢?
在这里插入图片描述
我们发现a1是1而a2是随机值,成员变量的初始化顺序是由它们在类中的声明次序决定的。与其在初始化列表中的先后次序无关。
在A类中_a2比_a1先声明,因此_a2会先于_a1初始化。

应该按照成员变量在类中声明的顺序初始化它们,或者更改成员变量的声明顺序以反映期望的初始化顺序。

class A
{
public:
    A(int a)
       :_a1(a)//现在是_a1先初始化
       ,_a2(_a1)//然后_a2再初始化
   {}
    
    void Print() {
        cout<<_a1<<" "<<_a2<<endl;
   }
private:
    int _a1;//声明顺序改为先_a1
    int _a2;//后_a2
};
int main() {
    A aa(1);
    aa.Print();
}

在这里插入图片描述

1.3 隐式类型转换

class A
{
public:
    A(int a)
       :_a1(a)
   {}
    
    void Print() {
        cout<<_a1<<" "<<_a2<<endl;
   }
private:
    int _a1;
};
int main() {
    A aa1(1);
    aa1.Print();
    A aa2=2;
    aa2.Print();
}

在这里插入图片描述
构造函数不仅可以构造与初始化对象,对于单个参数或者除第一个参数无默认值其余均有默认值的构造函数,还具有类型转换的作用。这个构造函数允许构造函数参数类型到类类型的隐式类型转换。这种转换使得单个值可以被视为是该类的一个实例,即使没有显式地调用构造函数。

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

    void Print() {
        cout << _a1<< endl;
    }
private:
    int _a1;
};
int main() {
    A aa2 = 2;
    A& aa2 = 3;
    aa2.Print();
}

A& aa2 = 3;试图将一个整型字面量3赋给A类型的引用aa2。这行代码会导致编译错误,原因如下:

  1. 引用的基本要求:在C++中,引用必须绑定到一个已经存在的对象上。引用本质上是对象的别名,它不能像指针那样独立存在
  2. 引用与临时对象:临时变量具有常性,在引用前应该加const(const A& aa2)
    正确用法:
    const A& aa1=A(3);
    //或者
    const A& aa2 = 3;
A aa3(4);
A& aa4=aa3;
class Stack
{
public:
	void Push(const A& a)
	{
			//
	}
};

压栈

Stack st;
A aa3(3);
st.Push(aa3);

st.Push(4);

直接用隐式类型转换就方便了很多

1.4 explicit关键字

如果不想让隐式类型转换发生,我们就需要用 explicit修饰构造函数,禁止类型转换在这里插入图片描述
在这里插入图片描述
单参构造函数,没有使用explicit修饰,具有类型转换作用
C++11及以后版本版本支持多个参数隐式类型转换

class A
{
public:
	//explicit A(int a1, int a2)
	A(int a1, int a2)
		:_a1(a1)
		,_a2(a2)
	{}

private:
	int _a1;
	int _a2;
};
int main()
{
    A aa={1,2};
	return 0;
}

如果不想让隐式类型转换发生可以加上explicit关键字。

感谢大家观看!!!

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

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

相关文章

WP-AutoPostPro 汉化版: WordPress自动采集发布插件

WP-AutoPostPro 是目前最好用的WordPress自动采集发布插件&#xff0c;最大的特点是可以采集来自于任何网站的内容并自动发布到你的WordPress站点。真正做到可以采集任何网站的内容并自动发布&#xff0c;采集过程完全自动进行无需人工干预&#xff0c;并提供内容过滤、HTML标签…

C++从入门到精通——模板

模板 前言一、泛型编程二、函数模板函数模板的概念函数模板格式示例 函数模板的原理函数模板的实例化隐式实例化显式实例化示例 auto做模板函数的返回值模板参数的匹配原则总结 三、类模板类模板的定义格式类模板的实例化 前言 C模板是C语言中的一种泛型编程技术&#xff0c;可…

用ESP32的ADC引脚,结合分压电路测量电压

该代码基于ESP32&#xff08;Arduino库&#xff09;实现ADC&#xff08;模拟数字转换器&#xff09;数据采集。它配置ADC参数、获取校准特性&#xff0c;循环采样并计算平均值&#xff0c;将ADC读数转换为电压&#xff0c;考虑分压电阻影响&#xff0c;计算实际电压值&#xff…

SpringBoot 根据不同环境切换不同文件路径

最简单的办法就是使用多个 application.yml 配置文件 。一个叫 application-test.yml 测试用&#xff1b;另一个是正式使用的 application-prod.yml 。win环境下大部分是开发测试时候使用的&#xff0c;服务正式上线需要部署在Linux服务器上又换成了Linux。但开发初期或者项目…

SEGGER Embedded Studio IDE移植FreeRTOS

SEGGER Embedded Studio IDE移植FreeRTOS 一、简介二、技术路线2.1 获取FreeRTOS源码2.2 将必要的文件复制到工程中2.2.1 移植C文件2.2.2 移植portable文件2.2.3 移植头文件 2.3 创建FreeRTOSConfig.h并进行配置2.3.1 处理中断优先级2.3.2 configASSERT( x )的处理2.3.3 关于系…

Unity3D 爆火的休闲益智游戏工程源码/3D资源 大合集

Unity3D休闲益智游戏工程源码大合集 一、关卡类游戏工程源码二、跑酷类游戏工程源码三、消除合成类游戏工程源码四、棋牌类游戏工程源码五、RPG(角色扮演)类游戏工程源码六、FPS&#xff08;射击&#xff09;类游戏工程源码十、Unity3D工艺仿真六、Unity游戏资源1、Unity3D 吃鸡…

金融时报:波场亮相哈佛大学并举办TRON Builder Tour活动

近日,波场TRON作为顶级白金赞助商出席哈佛区块链会议并成功举办TRON Builder Tour哈佛站活动,引发海外媒体热议。美联社、金融时报、Cointelegraph等国际主流媒体及加密知名媒体均对此给予了高度评价,认为本次大会对TRON Builder Tour活动具有里程碑意义,彰显了波场TRON致力于促…

护眼台灯什么品牌好?台灯的十大品牌推荐

长时间的使用眼睛&#xff0c;出现疲劳感就会对眼睛造成伤害&#xff0c;最常见的场景就是青少年儿童学习看书&#xff0c;成年人晚上工作时。相信不少人就是这样度过的&#xff0c;因此数据表明目前中国近视患者超过6亿人。所以想要拥有一个良好的视力健康一款光源合适的台灯是…

【数据结构】栈和队列(链表模拟队列)

学习本章节必须具备 单链表的前置知识&#xff0c; 建议提前学习&#xff1a;点击链接学习&#xff1a;单链表各种功能函数 细节 详解 本章节是学习用 单链表模拟队列 1. 单链表实现队列 思路如下 队列&#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数…

代码中哪些复杂的结构图是怎么画出来的?

最近找到一个在线的代码架构图生成器&#xff0c;你只要画出结构图&#xff0c;就会自动生成代码示意图&#xff1a; https://asciiflow.com/#/

计算机网络—TCP协议详解:协议构成、深度解析(3)

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;マリンブルーの庭園—ずっと真夜中でいいのに。 0:34━━━━━━️&#x1f49f;──────── 3:34 &#x1f504; ◀️…

变频电源都有哪些故障?

变频电源是一种可以将市电的交流电转换为频率可调的交流电的电力电子设备&#xff0c;它可以根据需求调整输出电压和频率&#xff0c;为设备运行提供稳定可靠的电源。但是在实际使用过程中常会遇到一些故障&#xff0c;今天纳米软件将介绍这些故障以及解决办法。 1. 短路 短路故…

开源项目实现简单实用的股票回测

1 引言 之前&#xff0c;尝试做股票工具一直想做的大而全&#xff0c;试图抓取长期的各个维度数据&#xff0c;然后统计或者训练模型。想把每个细节做到完美&#xff0c;结果却陷入了细节之中&#xff0c;最后烂尾了。 最近&#xff0c;听到大家分享了一些关于深度学习、时序…

【xhs爬虫软件】把小红书评论comment接口封装成GUI采集工具!

用Python开发爬虫采集软件&#xff0c;可自动抓取小红书评论数据&#xff0c;并且含二级评论。 小红书的评论接口URL是&#xff1a; https://edith.xiaohongshu.com/api/sns/web/v2/comment/page 开发者模式分析过程&#xff1a; 进而封装成GUI界面软件&#xff0c;如下&…

【Axure教程0基础入门】05动态面板

05动态面板 1.动态面板是什么&#xff1f; 一个用来存放多个元件的容器&#xff08;container&#xff09; 其中包含多个状态&#xff08;state&#xff09;&#xff0c;但同时只能显示一个 状态之间&#xff0c;可以通过交互动作&#xff08;action&#xff09;控制切换和动…

【Spring Cloud】服务容错中间件Sentinel进阶——五大规则

文章目录 Sentinel的概念和功能基本概念资源规则 重要功能流量控制熔断降级系统负载保护 SentineI 规则流控规则简单配置配置流控模式直接流控模式关联流控模式链路流控模式 配置流控效果 熔断规则慢调用比例异常比例异常数 热点规则热点规则简单使用热点规则增强使用 授权规则…

请编写函数fun,该函数的功能是:移动字符串中的内容,移动的规则如下:把第1到第m个字符,平移到字符串的最后,把第m+l到最后的字符移到字符串的前部。

本文收录于专栏:算法之翼 https://blog.csdn.net/weixin_52908342/category_10943144.html 订阅后本专栏全部文章可见。 本文含有题目的题干、解题思路、解题思路、解题代码、代码解析。本文分别包含C语言、C++、Java、Python四种语言的解法完整代码和详细的解析。 题干 请编…

Ai-WB2 系列模组SDK接入亚马逊

文章目录 前言一、准备二、亚马逊云物模型建立1. 注册亚马逊账号&#xff0c;登录AWS IoT控制台&#xff0c;[注册地址](https://aws.amazon.com/cn/)2. 创建好之后点击登录3. 创建物品以及下载证书 三、连接亚马逊云demo获取以及配置1. 下载源码2. 按照顺序执行下面指令3. 修改…

2024接口自动化测试高频面试题【建议收藏】

一、json和字典的区别&#xff1f; json就是一个文本、字符串&#xff1b;有固定的格式&#xff0c;格式长的像python字典和列表的组合&#xff1b;以key-value的键值对形式来保存数据&#xff0c;结构清晰&#xff0c;。可以说是目前互联网项目开发中最常用的一种数据交互格式…

buuctf——[CISCN2019 华北赛区 Day2 Web1]Hack World

buuctf——[CISCN2019 华北赛区 Day2 Web1]Hack World 1.根据提示&#xff0c;说明flag在表里 2.那就猜测存在sql注入&#xff0c;反手测试一波id1 3.尝试使用1--进行注释 4.直接丢进salmap里吧&#xff0c;不出意外多半是跑不出来 5.直接放入fuzz里进行测试 6.发现当我…