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

news2024/9/22 1:03:31

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.coloradmin.cn/o/1611641.html

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

相关文章

接口测试相关

接口测试&#xff0c;接口 接口是数据交互的入口和出口 接口是一套规范和标准 统一设计标准 前后端相对独立 扩展型灵活 接口文档。 接口测试 接口测试环境&#xff0c;运行程序&#xff0c;自己搭建环境 接口测试插件 谷歌postman 火狐 restclient java测试工具为j…

Docker - 入门基础

原文地址&#xff0c;使用效果更佳&#xff01; Docker - 入门基础 | CoderMast编程桅杆https://www.codermast.com/dev-tools/docker/docker-basic.html Docker架构 Docker 使用的是客户端-服务端&#xff08;C/S&#xff09;架构模式&#xff0c;使用远程 API 来管理和创建…

滚动条详解:跨平台iOS、Android、小程序滚动条隐藏及自定义样式综合指南

滚动条是用户界面中的图形化组件&#xff0c;用于指示和控制内容区域的可滚动范围。当元素内容超出其视窗边界时&#xff0c;滚动条提供可视化线索&#xff0c;并允许用户通过鼠标滚轮、触屏滑动或直接拖动滑块来浏览未显示部分&#xff0c;实现内容的上下或左右滚动。它在保持…

NASA数据集——TANSO-FTS 运行前 11 年收集的测量数据中得出二氧化碳(CO2)干空气摩尔分数(XCO2)的估计值

ACOS GOSAT/TANSO-FTS Level 2 bias-corrected XCO2 and other select fields from the full-physics retrieval aggregated as daily files V7.3 (ACOS_L2_Lite_FP) at GES DISC 简介 ACOS Lite 文件包含经过偏差校正的 XCO2 以及其他选定字段的每日汇总文件。ACOS 2 级标准…

Unity ECS

一&#xff1a;前言 ECS与OOP不同&#xff0c;ECS是组合编程&#xff0c;而OOP的理念是继承 E表示Entity&#xff0c;每个Entity都是一个有唯一id的实体。C表示Component&#xff0c;内部只有属性&#xff0c;例如位置、速度、生命值等。S表示System&#xff0c;驱动实体的行为…

js 函数节流和函数防抖及区别详解

文章目录 1. 前言2. 函数节流3. 函数防抖4. 总结 1. 前言 浏览器中总是有一些操作非常耗费性能。所以就有了函数节流和函数防抖来提高浏览器性能。 函数节流&#xff1a;频繁触发一个事件时候&#xff0c;每隔一段时间&#xff0c;函数只会执行一次。 函数防抖&#xff1a;当触…

js 遍历数据结构,使不符合条件的全部删除

js 遍历数据结构&#xff0c;使不符合条件的全部删除 let newSourceJSON.parse(JSON.stringify(state.treeData))state.expandedKeys[]checkedKeys.map((item:any)>{loop(newSource,{jsonPath:item.split(&)[1]},state.expandedKeys)})function removeUnwantedNodes(tre…

react 项目路由配置(react-router-dom 版本 v6.3、v6.4)

根据 react-router-dom 的版本&#xff0c;有不同的方式 一、react-router-dom v6.3 用到的主要 api: BrowserRouteruseRoutesOutlet 下面是详细步骤&#xff1a; 1、index.js BrowserRouter 用来实现 单页的客户端路由使用 BrowserRouter 包裹 App放在 顶级 位置&#x…

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

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

使用Cesium ion将 Sketchfab 3D 模型添加到您的GIS应用中

您现在可以将 Sketchfab 中的 3D 模型导入 Cesium ion 中以创建 3D 块&#xff0c;从而更轻松地为地理空间体验创建上下文和内容。 Sketchfab 是 Epic Games 的一部分&#xff0c;也是使用最广泛的 3D 资产市场之一。自 2012 年推出以来&#xff0c;已有超过 1000 万用户使用 …

《设计模式之美》- 总结

《设计模式之美》- 总结 第一章 概述 1.1 为什么学习代码设计 编写高质量的代码应对复杂代码的开发程序员的基本功职业发展的必备技能 1.2 如何评价代码的质量 1.2.1 可维护性 可维护性代码的特性&#xff1a;代码简洁、可读性好、可扩展性好代码分层结构清晰、模块化程度…

Spring Boot + Thymeleaf 实现的任务发布网站

角色&#xff1a; 管理员雇主雇员 功能 雇主&#xff1a;登录、注册、发布任务、选择中标雇员、评价雇员雇员&#xff1a;登录、注册、查看任务列表、投标任务、收藏任务、完成任务管理员、登录、任务管理、雇主管理、雇员管理 部分功能截图 部署 导入数据库…

【剪映专业版】13快速为视频配好音:清晰、无噪声、对齐

视频课程&#xff1a;B站有知公开课【剪映电脑版教程】 使用场景&#xff1a;视频无声音或者视频有声音但是需要更改声音 时间指示器在哪里&#xff0c;就从哪里开始 红色按钮&#xff1a;开始录音 声音波纹&#xff1a;蓝色最佳&#xff0c;黄色或红色声音太大&#xff0c;…

【Django】学习笔记

文章目录 [toc]MVC与MTVMVC设计模式MTV设计模式 Django下载Django工程创建与运行创建工程运行工程 子应用创建与注册安装创建子应用注册安装子应用 数据模型ORM框架模型迁移 Admin站点修改语言和时区设置管理员账号密码模型注册显示对象名称模型显示中文App显示中文 视图函数与…

CCIE-16-PIM

目录 实验条件网络拓朴实验环境实验目的 开始实验实验1&#xff1a;PIM-DM配置PIM域中的路由&#xff0c;开启PIM-DM组播路由功能&#xff0c;验证组播情况 实验2&#xff1a;PIM-SM&#xff08;静态RP&#xff09;配置PIM域中的路由&#xff0c;开启PIM-SM组播路由功能&#x…

IntelliJ IDEA运行发布传统Java Web Application项目

接 重温8年前项目部署 要求&#xff0c;如何改用IntelliJ IDEA运行发布传统 Java Web Application项目呢&#xff0c;简述步骤如下&#xff1a; 一、下载源码 源码&#xff1a;https://github.com/wysheng/kindergarten 下载后的本地项目路径&#xff1a;/Users/songjianyon…

美容预约小程序:简单三步,开启高效预约模式

在当今的数字化时代&#xff0c;一个小程序可以极大地提高美容院的效率和客户满意度。下面我们将详细说明如何通过以下步骤来搭建一个美容院预约小程序。 首先&#xff0c;你需要注册并登录到乔拓云网&#xff0c;这是 一个在线平台&#xff0c;可以帮助你快速创建并管理你的小…

SpringBoot集成FTP

1.加入核心依赖 <dependency><groupId>commons-net</groupId><artifactId>commons-net</artifactId><version>3.8.0</version></dependency> 完整依赖 <dependencies><dependency><groupId>org.springfra…

(四)SQL面试题(连续登录、近N日留存)学习简要笔记 #CDA学习打卡

目录 一. 连续登录N天的用户数量 1&#xff09;举例题目 2&#xff09;分析思路 3&#xff09;解题步骤 &#xff08;a&#xff09;Step1&#xff1a;选择12月的记录&#xff0c;并根据用户ID和登录日期先去重 &#xff08;b&#xff09;Step2&#xff1a;创建辅助列a_rk…

maven问题汇总

​ 1、报错 failed to transfer from http://0.0.0.0/ during a previous attempt. com.byd.xxx:xxx-parent:pom:1.1.0-SNAPSHOT failed to transfer from http://0.0.0.0/ during a previous attempt. This failure was cached in the local repository and resolution is no…