【C++11】详谈隐式类型转换

news2024/10/4 15:33:46
图片名称
🎉博主首页: 有趣的中国人

🎉专栏首页: C++进阶

🎉其它专栏: C++初阶 | Linux | 初阶数据结构

在这里插入图片描述

小伙伴们大家好,本片文章将会讲解 C++11中 隐式类型转换 的相关内容。


如果看到最后您觉得这篇文章写得不错,有所收获,麻烦点赞👍、收藏🌟、留下评论📝。您的支持是我最大的动力,让我们一起努力,共同成长!

文章目录

  • `1. 关于C++11`
    • ==<font color = blue><b>🎧1.1 C++11简介🎧==
    • ==<font color = blue><b>🎧1.2 C++11官方介绍🎧==<br>
  • `2. 统一的列表初始化`
    • ==<font color = blue><b>🎧2.1 C/C++98 数组 & 结构体 初始化🎧==
    • ==<font color = blue><b>🎧2.2 单/多参数类型的隐式类型转换🎧==
  • `3. STL 中的 Initializer_list 构造函数`
    • ==<font color = blue><b>🎧3.1 Initializer_list 🎧==
    • ==<font color = blue><b>🎧3.2 Initializer_list 初始化容器 🎧==



1. 关于C++11


🎧1.1 C++11简介🎧


在2003年C++标准委员会曾经提交了一份技术勘误表(简称TC1), 使得 C++03 这个名字已经取代了 C++98 成为 C++11 之前的最新C++标准名称

不过由于 C++03(TC1) 主要是对 C++98 标准中的漏洞进行修复,语言的核心部分则没有改动,因此人们习惯性的把两个标准合并称为 C++98/03 标准。从 C++0x 到C++11,C++ 标准10年磨一剑,第二个真正意义上的标准珊珊来迟。

相比于 C++98/03,C++11 则带来了数量可观的变化,其中包含了约 140 个新特性,以及对 C++03 标准中约 600 个缺陷的修正,这使得 C++11 更像是从 C++98/03 中孕育出的一种新语言。相比较而言,C++11 能更好地用于系统开发和库开发、语法更加泛华和简单化、更加稳定和安全,不仅功能更强大,而且能提升程序员的开发效率,公司实际项目开发中也用得比较多,所以我们要认真去学习。

🎧1.2 C++11官方介绍🎧



🎉官网链接: C++11



2. 统一的列表初始化


🎧2.1 C/C++98 数组 & 结构体 初始化🎧


在C/C++98中,标准允许使用花括号 { } 对数组或者结构体元素进行统一的列表初始值设定。比如:

struct Point
{
	int _x;
	int _y;
};

int main()
{
	// struct Point类型的初始化
	Point p = { 100, 99 };
	int arr1[10] = { 10, 20, 30 };
	return 0;
}

🎧2.2 单/多参数类型的隐式类型转换🎧


对于自定义类型,如果是单参数类型的构造函数,会发生隐式类型转换,例如:

class A
{
public:
	A(int x)
		: _x(x)
		, _y(x)
	{}

	void Print()
	{
		cout << _x << ":" << _y << endl;
	}

private:
	int _x;
	int _y;
};

int main()
{
	// 隐式类型转换
	A aa1 = 1;
	A aa2 = { 2 };
	
	// 直接构造
	A aa3(3);
	
	// 也可以省略等号
	A aa4{ 1 };
	return 0;
}

如果是多参数类型的构造函数,同样会发生隐式类型转换,例如:

class A
{
public:
	A(int x, int y)
		: _x(x)
		, _y(y)
	{}
	
private:
	int _x;
	int _y;
};

int main()
{
	// 隐式类型转换
	A aa1 = { 1, 2 };
	
	// 也可以省略等号
	A aa2{ 3, 4 };

	// 可以省略等号
	A aa3(4, 5);

	return 0;
}

如果不想发生隐式类型的转换,可以在构造函数之前加上 explicit 关键字,例如:

class A
{
public:
	// 不允许发生隐式类型转换
	explicit A(int x, int y)
		: _x(x)
		, _y(y)
	{}
	
	// 不允许发生隐式类型转换
	explicit A(int x)
		: _x(x)
		, _y(x)
	{}

	void Print()
	{
		cout << _x << ":" << _y << endl;
	}

private:
	int _x;
	int _y;
};

int main()
{
	// 下面两行会报错
	A aa0 = 1;
	A aa3 = { 1 };
	A aa1 = { 1, 2 };
	
	// 以下可以正常使用
	A aa2{ 3, 4 };
	A aa4{ 0 };
	
	return 0;
}

关于单/多参数类型的构造函数的解释:

  1. 对于形如 A aa1 = { 1, 2 };的构造,编译器处理时会发生以下两个步骤:
    • 首先会利用 { } 中的值调用构造函数生成一个临时变量;
    • aa1 进行拷贝构造。
    • 但是编译器会优化成直接构造。
  2. 对于形如 A aa2{ 3, 4 };的构造,就会直接调用构造函数,不会产生临时变量。
  3. 如果产生了临时变量,我们知道临时变量具有常性,就有:
    • 如果用:A& aa1 = { 1, 2 };会报错。
    • 得用:const A& aa1 = { 1, 2 };



3. STL 中的 Initializer_list 构造函数


我们这里先以 vector 为例。


🎧3.1 Initializer_list 🎧


initializer_listC++11 引入的一种标准库类型,用于方便地初始化同一种类型的元素列表。initializer_list 允许通过大括号 { } 语法进行初始化,例如:

  std::initializer_list<int> my_list = {1, 2, 3, 4, 5};

这里 my_list 是一个包含了整数元素 {1, 2, 3, 4, 5}initializer_list<int> 对象。


主要特点包括:

  1. 不可变性: 一旦初始化完成,initializer_list 中的元素不可再被修改。
  2. 轻量:initializer_list 本身只包含指向数据的指针和长度信息,因此非常轻量,适合在函数参数传递和对象构造时使用。
  3. 语法简洁: 通过 { } 初始化列表的语法,能够清晰地指定一组初始值,而不需要显式地调用构造函数。


底层实现逻辑:

namespace std 
{
    template<class T>
    class initializer_list 
    {
    public:
        using value_type      = T;
        using reference       = const T&;
        using const_reference = const T&;
        using size_type       = size_t;

        initializer_list() noexcept; // 构造一个空的 initializer_list
        size_type size() const noexcept; // 返回列表中元素的个数
        const T* begin() const noexcept; // 返回指向第一个元素的指针
        const T* end() const noexcept; // 返回指向最后一个元素之后的位置的指针
    };
}

🎧3.2 Initializer_list 初始化容器 🎧


当使用vector时,每次都用不同数量的值初始化容器,那么就要写非常多的构造函数来实现这个需求。

但是用Initializer_list就可以一劳永逸的解决这个问题。

int main()
{
	// 用 10 个 1 构造 vector
	vector<int> v(10, 1);

	initializer_list<int> il = { 10,9,8,5 };
	vector<int>(il);
	
	vector<int> v1 = { 1,2,3,4,5,6 };
	vector<int> v2({ 9,8,7,6,5,4 });

	return 0;
}

两种构造的区别:

  1. 对于:vector<int> v1 = { 1,2,3,4,5,6 };
    • 编译器会先将{ 1,2,3,4,5,6 }识别成initializer_list
    • 然后调用Initializer_list的构造,中间生成临时变量;
    • 最后拷贝构造给v1
    • 但是编译器会优化成直接构造。
  2. 对于:vector<int> v2({ 9,8,7,6,5,4 });
    • 这就是直接构造。
  3. 总的来说,形如:X自定义 = Y类型 一定发生了 隐式类型转换。X 支持 Y 为参数类型构造就可以。

对于 map 的 initializer_list 的构造

map 支持 pair 类型的 initializer_list 的构造:

在这里插入图片描述

这里的 value_type 就是 pair。


map构造代码示意:

int main()
{
	// 方法一:
	pair<string, string> kv1 = { "include", "包括" };
	pair<string, string> kv2 = { "sort","排序" };
	map<string, string> dict1({ kv1, kv2 });

	// 方法二:
	map<string, string> dict2 = { kv1, kv2 };
	map<string, string> dict3 = {{"include", "包括"}, { "sort","排序" }};
	
	return 0;
}

两种构造区别:

  1. 对于方法一:
    • 因为pair支持双参数的构造函数,所以{ "include", "包括" }{ "sort","排序" }会发生隐式类型的转换生成临时变量,然后再拷贝构造给kv1kv2(编译器会优化成直接构造);
    • 因为map 支持 pair 类型的 initializer_list 的构造,因此直接使用:map<string, string> dict1({ kv1, kv2 });即可
  2. 对于方法二:
    • {"include", "包括"}, { "sort","排序" }会被识别成两个pair类型;
    • 然后外层大括号会被识别成initializer_list,进行隐式类型转换,在进行拷贝构造(会被优化)。

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

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

相关文章

基于Java的高校校园点餐系统

开头语&#xff1a; 你好&#xff0c;我是计算机专业的学长&#xff0c;如果你对高校校园点餐系统感兴趣或有相关开发需求&#xff0c;欢迎联系我。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;JSP技术 工具&#xff1a;Eclipse、Tomcat 系统展示…

示例:WPF中如何不卡顿页面的情况加载大量数据

一、目的&#xff1a;在开发过程中经常会遇到一个ListBox列表里面需要加载大量数据&#xff0c;但是加载过程中会假死卡顿影响用户体验&#xff0c;或者是你的主页面加载了大量控件&#xff0c;或者切换到一个有大量元素的页面都会有这种体验&#xff0c;因为加载的都是UI元素不…

网工内推 | 中国电信、香港宽频系统工程师,CCIE认证优先,最高年薪25w

01 中国电信股份有限公司浙江分公司 &#x1f537;招聘岗位&#xff1a;系统架构师 &#x1f537;岗位职责&#xff1a; 1、做好客户网络和信息安全产品的解决方案支撑、交付及后续运营维护&#xff0c;做好相关产数项目的支撑。 2、根据信息安全管理要求&#xff0c;负责客户…

【论文精读】RayMVSNet

今天读的是发表在CVPR2022上的无监督MVS文章&#xff0c;作者来自于国防科大。 文章链接&#xff1a;RayMVSNet 项目地址&#xff1a;Github Abstract 作者希望直接优化每个camera ray上的深度值&#xff0c;所以提出这个RayMVSNet来学习1D implicit field的序列预测。使用了…

SCI一区TOP|常青藤优化算法(IVYA)原理及实现【免费获取Matlab代码】

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4 .参考文献5.代码获取 1.背景 2024年&#xff0c;M Ghasemi受到自然界中常青藤生长行为启发&#xff0c;提出了常青藤优化算法&#xff08;Ivy Algorithm, IVYA&#xff09;。 2.算法原理 2.1算法思想 IVYA模拟常青…

嵌入式web 服务器boa的编译和移植

编译环境&#xff1a;虚拟机 ubuntu 18.04 目标开发板&#xff1a;飞凌OKA40i-C开发板&#xff0c; Linux3.10 操作系统 开发板本身已经移植了boa服务器&#xff0c;但是在使用过程中发现POST方法传输大文件时对数据量有限制&#xff0c;超过1M字节就无法传输&#xff0c;这是…

python运算符和表达式实战

1.判断回文数 回文数就是将其反向排列&#xff0c;与原来相等 n1 n2 int(input("请输入&#xff1a; ")) t 0 while n2>0 :# 取余数t t*10n2%10# 取整数n2 // 10 if n1 t:print("是回文数") else:print("不是回文数") 2.字符串转换&…

2024青海三支一扶报名流程图解❗

报考公告 1、招考人数&#xff1a; 1910 人 2、报名时间&#xff1a;6月20-6月25 3、笔试时间&#xff1a;7月6日 4、笔试内容&#xff1a;综合知识和能力素质测验 &#x1f534;线上报名流程图解 一、本次报名采用线上报名方式&#xff0c;考生需登录《青海省人事考试信息网》…

【漏洞复现】契约锁电子签章平台 add 远程命令执行漏洞(XVE-2023-23720)

0x01 产品简介 契约锁电子签章平台是上海亘岩网络科技有限公司推出的一套数字签章解决方案。契约锁为中大型组织提供“数字身份、电子签章、印章管控以及数据存证服务”于一体的数字可信基础解决方案,可无缝集成各类系统,让其具有电子化签署的能力,实现组织全程数字化办公。通…

连接Huggingface报requests.exceptions.SSLError错误

最近在学习使用 SHAP 算法解释 BERT 模型的输出结果&#xff0c;然而在从 Huggingface 上导入模型和数据集的过程中出现了网络连接相关的错误&#xff0c;本文用于记录错误类型和解决错误的方法。 1 代码示例 SHAP 官方展示的代码如下&#xff1a; import datasets import nu…

基于SSM的个人博客管理系统

有需要请加文章底部Q哦 可远程调试 基于SSM的个人博客管理系统 一 介绍 个人博客管理系统基于SSM框架开发&#xff0c;数据库mysql&#xff0c;前端layui。系统角色分为用户和管理员。(附带配套设计文档!) 技术栈&#xff1a;JavaSSM框架mysqllayuiIDEAMaventomcat8.5jdk1.8 …

大语言模型架构---Transformer 模型

文章目录 输入编码多头自注意力机制前馈网络层编码器解码器当前主流的大语言模型都基于 Transformer 模型进行设计的。Transformer 是由多层的多头自注意力(Multi-head Self-attention)模块堆叠而成的神经网络模型。原始的 Transformer 模型由编码器和解码器两个部分构成,而…

基于PLC的全自动洗衣机控制系统课设

一、设计题目 1.1课题内容 根据设计参数和控制要求&#xff0c;设计一全自动洗衣机&#xff0c;画出其运行框图及梯形图控制程序的编制&#xff0c;并画出硬件接线图。 1.2设计参数 1.3控制要求 &#xff08;1&#xff09;按下启动按扭及水位选择开关&#xff0c;开始进水直…

PHP转Go系列 | 变量常量的使用姿势

大家好&#xff0c;我是码农先森。 变量 在 PHP 语言中&#xff0c;初始化变量虽然只有一行&#xff0c;其实包含了两步&#xff0c;一是声明变量&#xff0c;二是赋值给变量&#xff0c;同一个变量可以任意再赋值任何类型的数据。 <?php// 初始化变量 $name "man…

[linux] 系统的基本使用

用户系统&#xff1a; 之前提到&#xff0c;linux是个多用户系统&#xff0c;所以要使用linux&#xff0c;首先你得是个用户 用户&#xff1a;普通用户管理员 每一个用户有自己的用户名密码&#xff0c; 会话(session):一个终端使用服务器的全过程 从你用户登录&#xff0c;到你…

Java 读取Excel导入数据库,形成树状结构

最近开发过程中遇到一个Excel的导入的功能,因为导入的数据结构具有层次结构,经过一番研究,最终得以实现,所有写下该文章,记录过程,供以后参考。 下图是导入Excel的数据结构: 使用POI解析Excel,数据封装然后进行入库。下面是核心代码。 @Overridepublic KnowledgeBase…

Linux内核开发-编译内核源码

前言 大部分公司的所谓的Linux内核工程师主要工作是基于社区开源内核进行定制化修改&#xff0c;基本不会有机会向上游提供patch&#xff0c;仅限于公司内部业务的修修补补。 作为内核开发工程师两年多&#xff0c;精力一直被公司业务消耗&#xff0c;所有的内核知识都来自于…

微信小程序-上拉加载和下拉刷新

一.上拉加载 微信小程序的上拉加载使用onReachBottom()&#xff0c;写在.js文件里面的Page方法里面。 onReachBottom(){//上拉自动更新到4&#xff0c;5&#xff0c;6wx.showLoading({title: 数据加载中...,})setTimeout(()>{const lastNumthis.data.numList[this.data.nu…

nodejs——ejs模版遇到原型链污染产生rce

[GYCTF2020]Ez_Express 打开是一个登陆框 在源代码中找到 在代码里找到敏感关键字 找到merge 想到原型链污染 这里登陆只能用ADMIN才能登陆成功 但是这里index.php又设置了一个waf ban了admin的大小写 这里需要绕过这个waf 看注册这段代码 用的是这个toUpperCase()函数 之前…

Ubuntu安装Vins-Fusion(1) —— Ubuntu18.04安装vins

目录 前言 1、准备1.1 安装ROS1.2 安装 Ceres Solver 2、安装 VINS-Fusion3、测试&#xff08;EuRoC MAV 数据集&#xff09;3.1、下载数据集3.2 Monocualr camera IMU3.3 Stereo cameras IMU3.4 Stereo cameras 参考 前言 VINS-Fusion 是一种基于优化的多传感器状态估计器&…