C++相关概念和易错语法(7)(初始化列表、隐式类型转换、友元)

1.初始化列表

初始化列表是集成在构造函数里面的,对象在创建的时候一定会调用构造函数(就算不显式定义,也会自动生成并调用)。初始化列表就是这些对象的成员变量在创建的时候初始化的地方。

下面是使用的例子,可以先看看:

注意:这个格式只能是:冒号开始,逗号分隔,成员变量后只能用括号(包括对象、赋值变量),不能使用赋值=,内置类型括号内是什么赋值什么,自定义类型就用括号里的值调用它的构造函数

我们需要将这种写法和我们之前写的构造函数做对比:

这个特性在某些场景非常关键,在以下两种场景中必须使用初始化列表:

(1)有的变量只有在初始化的时候赋值,比如引用int&(不能出现空引用),const修饰的变量(常属性)

(2)当我们不显式实现构造函数时,编译器会自动生成默认构造函数,其中的规则有一条为——对于自定义类型会去调用它的默认构造。这里有个问题就是,如果这个自定义类型显式实现了一个带参数的构造函数,那么它无法生成默认构造,编译器是无法调用它的,这个时候就会报错。

下面是实例:

我们发现如果没有初始化列表,这两种情况是无解的。对于(1),不管我们怎么写构造函数,引用和const变量在创建时都无法被赋值。对于(2)更是如此,根本不支持在大括号里去调用构造函数,只有初始化的时候才可以。

2.缺省值和初始化列表的关系

之前我们就提到调用构造函数前会先走一遍缺省值,后续的调用本质上是一种覆盖。

更准确地说,缺省值是给初始化列表使用的。假设我们在成员变量声明处写了int _a = 1,如果我们没有自己写初始化列表,而是在函数体内写了_a = 2,那么当_a创建时会自动创建一个初始化列表,其中_a初始化时在初始化列表中赋的值就是缺省值,也就是_a(1),后续再进入函数体,将_a赋值为2。

值得注意的是初始化列表中对成员变量进行初始化的顺序是按照在类中声明的顺序进行的,而不是按照初始化列表中代码的顺序进行的,同样地,这些成员变量在空间中开辟的顺序就是按照声明顺序进行的。

如果我们成员变量中有自定义类型的对象,且这个自定义类型中有含参的构造函数,那么我们一定要显式实现这个初始化列表,否则一定会报错。

如果我们显式实现了初始化列表,如在初始化列表中写了_a(1),在成员变量声明处写了缺省值int _a = 2,这个时候在编译器创建变量并初始化时就会直接忽略我们声明处的缺省值。

初始化列表或者缺省值处我们可以自由地写表达式或者函数,都能实现我们想要的效果。

3.内置类型隐式转换成自定义类型

这是一个相对来说比较难理解的地方,我们所知的int、char、double、int*等可以转换成类的类型,如A a = 3。这里需要注意的是数组不是内置类型,它属于自定义类型(int []),因此如A a = "Hello"这种操作是不行的。

转换的实质:

默认生成拷贝构造是const A& tmp,有const修饰,也不需要担心默认的拷贝构造会被const拦截住

注意这里是我们的逻辑,而编译器会进行优化,实际并不是这样,后面会提及。

但是,不是所有的情况都可以实现隐式类型转换,是要看自定义类型的构造函数有几个参数来决定的。下面我分情况来讲解一下:

(1)无参的构造函数:不支持任何隐式类型转换

(2)含一个参数的构造函数:支持所有内置类型的转换,转换的规则就是创建一个临时的对象(这个对象具有常属性,里面成员变量的值不能修改),这个内置类型的值就作为它构造函数的参数传过去。

传的参数没有要求,遵循C语言内置类型之间的隐式类型转换规则。

(3)多个参数:支持所有内置类型的转换,但根据规则我们需要多个内置类型才能隐式转换成自定义类型,用大括号括起来。注意内置类型的数量要和构造函数的参数个数相同,除非有缺省值,这和我们之前遇到的构造函数的初始化类似。

不加=也是可以的,要学会识别。

当然,隐式类型转换也存在它的风险,如果我们不想发生隐式类型转换,可以在构造函数前面加上explicit修饰

注意隐式类型转化也可以嵌套,在有的情况下还是很好用的


#include <iostream>
using namespace std;class A
{
public:A(int a = 0, int b = 0):_a(a),_b(b){}int _a;int _b;
};class B
{
public:B(int c, A d):_c(c),_d(d._a, d._b){}private:int _c;A _d;};int main()
{B b1 = { 1,{2,3} };return 0;
}

4.友元

就在上面的那段代码,我们会注意到A的_a和_b是共有的,如果是私有的,那么如何处理呢?

(1)友元类

首先像构造和析构函数这种特殊的函数没有返回值,不是标准的函数形式,所以无法使用友元函数。因此我们要使用友元类来处理这种情况。声明友元类后,A的友元B可以访问A的所有私有变量以及所有的函数。


#include <iostream>
using namespace std;class A
{friend class B;public:A(int a = 0, int b = 0):_a(a),_b(b){}
private:int _a;int _b;
};class B
{
public:B(int c, A d):_c(c),_d(d._a, d._b){}private:int _c;A _d;};int main()
{B b1 = { 1,{2,3} };return 0;
}

(2)友元函数

如果B类或全局的函数想要访问A类的私有成员,我们可以采用友元函数的方式,用friend+函数声明即可。一个函数可以是多个类的友元函数,访问的时候和普通函数相同。

要注意友元函数的几个特性:

a.友元函数不能用const修饰(规定)

b.在A声明的友元函数并不是A的成员函数,也没有this的概念

c.友元函数可以在类定义的任何地方声明(不受访问限制符private的作用)

(3)内部类

内部类和我们理解的成员变量不太一样,它是独立的,在计算sizeof的时候不会计算内部类的大小。其实内部类仅仅是受到类域的限制,表明它是这个外部类的专属类。

内部类默认就是外部类的友元,内部类可访问外部类的私有成员;但是外部类并不默认是内部类的友元函数,不能直接访问。


 

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

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

相关文章

香港服务器_免备案服务器有哪些正规的?企业、建站方向

香港服务器&#xff0c;是最受欢迎的外贸、企业建站服务器&#xff0c;在个人建站领域&#xff0c;香港服务器、香港虚拟主机都是首选的网站服务器托管方案&#xff0c;不仅其具备免备案的特点&#xff0c;而且国内外地区访问速度都很快。那么&#xff0c;现今2024年个人和企业…

项目如何部署

我们平常写的项目通常只能在本机上运行&#xff0c;要想项目能被远程访问就不得不谈到项目部署的知识&#xff0c;接下来我通过实际操作的操作让大家来上线一个vuespringBoot项目。 1.在windows上将vue部署到nginx服务器上 介绍nginx Nginx是一款高性能的Web服务器和反向代理服…

C#语法知识之循环语句

5、循环语句 文章目录 1、while思考1 斐波那契数列思考2 判断一个数是否为质数思考3 找出100以内的质数 2、do...while3、for思考1 找水仙花数思考2 乘法表 1、while 1、作用 让代码重复去执行 2、语法相关 while(bool类型值){//当满足条件时&#xff0c;就会执行while语句…

【GIS教程】ArcGIS做日照分析(附练习数据下载)

我国对住宅日照标准的规定是:冬至日住宅底层日照不少于1小时或大寒日住宅层日照不少于2小时(通常以当地冬至日正午12时的太阳高度角作为依据)。因冬至日太阳高度角最低&#xff0c;照射范围最小&#xff0c;如果冬至日12&#xff1a;00建筑物底层能够接收到阳光&#xff0c;那么…

Python数据可视化库—Bokeh与Altair指南

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 在数据科学和数据分析领域&#xff0c;数据可视化是一种强大的工具&#xff0c;可以帮助我们…

Docker - HelloWorld

原文地址&#xff0c;使用效果更佳&#xff01; Docker - HelloWorld | CoderMast编程桅杆https://www.codermast.com/dev-tools/docker/docker-helloworld.html 开始之前 在学习本小节之前&#xff0c;你必须确保你正确安装了 Docker&#xff0c;正确安装 Docker 是后续学习的…

墨子web3实时周报

蚂蚁集团Web3研发进展与布局 国内Web3赛道的领军企业——蚂蚁集团&#xff0c;凭借其在前沿科技领域的深耕不辍&#xff0c;已在Web3技术研发疆域缔造了卓越战绩。特别是在引领行业革新的关键时刻&#xff0c;集团于今年四月末震撼推出了颠覆性的Web3全套解决方案&#xff0c;…

java通过maven导入本地jar包的三种方式

一、引入lib下加载&#xff08;加载过后打包&#xff0c;以后再次使用不用再次导入&#xff09; 首先创建一个用于创建jar包的项目&#xff0c;并测试能否成功运行 讲项目打包 在需要引入的项目中创建lib目录 并把刚才打包的jar复制进去 通过dependency引入jar包 groupId、art…

读天才与算法:人脑与AI的数学思维笔记05_算法的幻觉

1. 自下而上 1.1. 代码在未来可以自主学习、适应并进行自我改进 1.2. 程序员通过编程教会计算机玩游戏&#xff0c;而计算机却会比教它的人玩得更好&#xff0c;这种输入寡而输出众的事情不大可能实现 1.3. 早在20世纪50年代&#xff0c;计算机科学家们就模拟该过程创造了感…

人工智能论文GPT-3(3):2020.5 Language Models are Few-Shot Learners;架构;训练数据集;开源

2.1 模型与架构 我们使用了与GPT-2相同的模型和架构&#xff0c;包括其中描述的改进初始化、预归一化和可逆分词技术&#xff0c;但有所不同的是&#xff0c;我们在Transformer的各层中使用了交替的密集和局部带状稀疏注意力模式&#xff0c;类似于Sparse Transformer 。为了研…

Flutter 的 showDialog 和 showCupertinoDialog 有什么区别?

我将我的 App 里用的 Flutter 升级到了 3.19&#xff0c;没想到&#xff0c;以前我用 showDialog 和 AlertDialog 组合创建的二次确认框&#xff0c;变得无敌难看了&#xff0c;大幅度增加了整个框的圆角和里面默认按钮的圆角。不得已&#xff0c;我必须修改一下&#xff0c;以…

算法练习|Leetcode189轮转数组 ,Leetcode56合并区间,Leetcode21合并两个有序链表,Leetcode2两数相加,sql总结

目录 一、Leetcode189轮转数组题目描述解题思路方法:切片总结 二、Leetcode56合并区间题目描述解题思路方法:总结 三、Leetcode21合并两个有序链表题目描述解题思路方法:总结 四、Leetcode2两数相加题目描述解题思路方法:总结 sql总结: 一、Leetcode189轮转数组 题目描述 给定…

C++|stack-queue-priority_queue(适配器+模拟实现+仿函数)

目录 一、容器适配器 1.1容器适配器概念的介绍 1.2stack和queue的底层结构 1.3deque容器的介绍 1.3.1deque的缺陷及为何选择他作为stack和queue的底层默认实现 二、stack的介绍和使用 2.1stack的介绍 2.2stack的使用 2.3stack的模拟实现 三、queue的介绍和使用 …

NotePad++联动ABAQUS

Abaqus 中脚本运行 1. 命令区kernel Command Line Interface &#xff08;KCLI&#xff09; execfile(C:\\temp\second develop\chapter2\pyTest1.py)2. CAE-Run Script File->Run Script 3. Abaqus command Abaqus cae noGUIscript.py(前后处理都可)Abaqus Python scr…

排序算法集合

912. 排序数组 趁着这道题总结下排序方法 1.快速排序 算法描述 1.从数列中挑出一个元素&#xff0c;称为"基准"&#xff08;pivot&#xff09;&#xff0c; 2.重新排序数列&#xff0c;所有比基准值小的元素摆放在基准前面&#xff0c;所有比基准值大的元素摆在基…

【网站项目】高校毕业论文管理系统小程序

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

人工智能论文GPT-3(2):2020.5 Language Models are Few-Shot Learners;微调;少样本Few-Shot (FS)

2 方法Approach 我们的基本预训练方法&#xff0c;包括模型、数据和训练&#xff0c;与GPT-2中描述的过程相似&#xff0c;只是模型规模、数据集规模和多样性&#xff0c;以及训练时长有所扩大&#xff0c;相对简单直接。 我们使用的上下文学习也与GPT-2相似&#xff0c;但在…

SpringCloud系列(8)--将服务提供者Provider注册进Eureka Server

前言&#xff1a;上一章节我们介绍了Eureka服务端的安装与配置&#xff0c;本章节则介绍关于微服务如何入职Eureka Server Eureka架构原理图 1、修改provider-payment8001子模块的pom.xml文件&#xff0c;引入Eureka Clinet的依赖&#xff0c;然后reolad一下&#xff0c;下载依…

Parade Series - CoreAudio Loopback

Scenario 鉴于业务场景需要&#xff0c; 经过技术路径探索&#xff0c; 发现 comtypes 兼容性过于混乱&#xff0c;故而考虑整合一个 CoreAudio 的轮子dll来解决实际问题&#xff01;std::StringStream ⇒ std::ios::binary ⇒ std::ofstream Loopback.dll #ifndef _DLL_C…

数学建模--非线性规划模型+MATLAB代码保姆式解析

目录 1.简单介绍 2.求解方法 3.适用赛题 4.典型例题及相关分析 &#xff08;1&#xff09;问题引入 &#xff08;2&#xff09;决策变量&约束条件 &#xff08;3&#xff09;确定目标函数 &#xff08;4&#xff09;建立数学模型 5.MATLAB代码祝逐字句讲解 1.简单…