友元,const成员,static成员变量,static成员函数

news2024/12/23 17:57:32

友元:

friend关键字:

1.友元函数:

语法: friend在类中修饰一个函数。 那么这个函数定义到全局时仍可以访问该类的私有成员的。 (定义时不需要用friend,而是需要在全局定义前,在要使用的成员的类里进行声明,声明时用friend修饰该函数。 在类中声明友元时,友元是public还是private都可以,都不影响友元的声明)。 注意friend修饰的函数并不是类中的函数,而是一个定义在类外的普通函数。  友元函数不能被被const修饰,指不能 friend int (Date& d) const;

Eg

而流插入是在全局中定义的。

Eg

此处的d._year以及d._month , d._day不会报错。但是如果没有声明友元,那么此处访问私有成员是不可以的。

  1. 友元类: 作用: 使可以在一个类里面使用另一个类的成员。

语法: friend class 类名;

Eg:

注意:在Time类中声明了 Date是Time的友元。 那么可以在Time类中可以使用Date类中的成员。   但这时并不能在 Date 类里面使用 Time类的成员。 只有在Date 类中声明了 Time是 Date的友元,那么才能在Date中使用Time的成员。(即 友元类的声明是单向的, 这一个是另一个的友元 并不一定 代表 另一个就是这一个的友元)

友元不能传递。 即 a 是 b 的友元 , b 是 c的友元。 但并不代表 a 就是 c的友元

内部类:

内部类和所在的类 都是 独立的类,内部类仅仅是放到所在的类的类域里面而已。 唯一与其定义到全局域不同的 是 这个类定义在一个类域中。 即内部类的特点就是在 类 域中 , 且其 内部类 天生 就是 该所在类 的友元。

Eg注意: sizeof(A) 的大小是 4。 即没有算内部类B的大小, 这是因为B和A是两个独立的类,唯一的关系就是 B 放到了A的类域中 且 B类 天生就是 A类的 友元。

Const成员函数:

原本的 this指针的类型是  类 类型*  const。 即 this 指针本身不能++或者--,即this指针本身不能改变。

当 const Date d1(2024,4,14);  后续如果传入 d1.Print(); 那么传入的实参类型是 const Date* 的。 而this指针的类型是  Date* const this; 这就导致权限放大。(因为const Date*的类型, 只能读,可以进行解引用,但不能通过解引用修改其值,即不能进行*this += 1; 这种操作。) (而本身this指针是 Date* const类型,这是可以 *this += 1;的,但不能修改this指针本身,即不能进行this += 1这种操作。)(因此实参类型为const Date* ,而形参类型为Date* const。这就是权限放大了,会报错)  

Eg1

Eg2

在成员函数后 加入const , 可以使this指针的类型 修改为 const Date* const 类型。而从const Date* 传入到 const Date* const类型,这是权限的缩小,是被允许的

取地址操作符的重载:

这两个运算符的重载一般不需要显式写,默认生成的即可使用

Eg:

初始化列表:构造函数的函数名和函数体。 初始化列表初始化的是存储在对象中的成员

记该类的成员有 3个不同类型的自定义类型 _s1 , _s2 , _s3 和一个内置类型 _a

语法:  : _s1(_s1的构造函数的对应参数) , _s2(_s2的构造函数的对应参数) , (_s3的构造函数的对应参数) , _a(要初始化的值)

Eg:

注意:对于用初始化列表初始化类型 是 相当于 在定义成员变量的时候进行初始化的, 因此const修饰的成员只能在初始化列表中进行初始化。

只能在初始化列表中进行初始化的成员类型:

  1. 引用类成员变量
  2. 没有默认构造函数的成员(该成员必须显式调用其构造函数的时候,必须在初始化列表中进行初始化)
  3. Const修饰的成员

如果没有显式写出初始化列表(或者没有写全。即写了 : _a(),_b(a)  那么后续也会默认生成),那么会自动自动生成一个初始化列表,但是默认生成的初始化列表对于内置类型 只会去调用默认构造。(即生成的为 : _a() , _b() , _c() , _m) ,因此如果内置类型没有默认构造函数,那么会编译报错 。

内置类型的缺省值实质上是给初始化列表使用的。 即如果成员_m在声明的时候给予缺省值 即int _m = 10;  那么如果没有显式写初始化列表,在编译器自动生成或者补齐的时候,内置类型会处理为  _m(10) 即 _m(缺省值)

构造函数是先走初始化列表再走函数体。

在实践中,能用初始化列表进行初始化尽量有初始化列表,不方便的话再在函数体中进行初始化。

初始化列表中对成员的初始化顺序是和成员声明的先后顺序保持一致的,与初始化列表中成员出现的先后顺序没有任何关系。

Eg: 此处输出的是  1  和  随机值 。 原因:先用_a1初始化_a2,此时的_a1为随机值。然后用 1 初始化 _a1。

因此推荐 初始化列表 中 成员出现的先后顺序 和 成员声明的先后顺序保持一致。 这样可增强可读性

声明时给缺省值的几种情况: 此处Stack 能这样给的前提是 Stack 类里有单参的构造函数。_a1,_a2也是同理。 因为实质上缺省值是 给初始化列表使用的。 走的其实是初始化列表.即_b1(1) , _ptr((int*)malloc(40)) , _pushst(10) , _a1(1) , _a2( { 1 , 2 } ) , _a3(_a2)

 

此处是声明给缺省值, 而不是初始化

单参数构造函数:

单参数的构造函数支持隐式类型转换。

此处A类中的构造函数是

        A(int a)

   {

        _a = a

   }

此处的 A aa3 = 3; 的是把  3  隐式转换,先构造出一个 类为 A 的临时对象(调用的该类的构造函数,从而构造出的临时对象)。 然后这个临时对象再拷贝构造 到 aa3 中。

如果要引用类型的话,应该是 const A& , 因为此处引用的实质上是 3 隐式转换 构造出的一个构造出的 类 为A 的临时对象, 而临时对象具有常性,因此要用const 修饰 A& 。 否则是权限的放大,出现编译错误。

编译器在遇到 连续的构造 + 拷贝构造 à 会优化为 直接构造。即 A aa3 = 3; 这里会被编译器优化为 直接构造。 但是它实质上的过程 就是上述的 先构造临时对象,再拷贝构造到 aa3 中。

推荐 要引用时 尽量用 const A& , 这样可以使得在st.Push(2); 时也可以传入,原因是2隐式转换  构造出一个A类的 临时对象, 而临时对象具有常量,因此要用const A& ,而不能用 A。 而已用const A& 也保证了传入的 实参不会被修改

取消单参数构造函数允许隐式转换的方法:

Explicit关键字:

Eg:

Explicit A(int a)

{

       _a = a;

}

此后 A a1 = 2; 是不被允许的。 因为 不允许 2 隐式转换构造 临时对象了。所以会编译错误。

静态成员: 静态成员变量不存储对象中,而是存储到静态区。

Static修饰的成员。

静态成员不能给缺省值。 因为缺省值是给初始化列表使用的。而初始化列表初始化的是存储到对象中的成员。 而静态成员存储到静态区,因此静态成员不能给缺省值。

静态成员属于所有对象。 因此可以在使用的时候可以 A : : _scount 。

即可以 cout << A : : _scount << endl;  也可以 cout << a._scount << endl;(不过如果_scount是private的 ,那么此处仍是不能访问该成员的)

而且静态成员存储到静态区。所以对象使用的 静态成员为同一个静态成员。

即 A a1 ; A a2;  A a3:   并且 int A : : _scount = 0 ; 那么 a1._scount , a2._scount , a3._scount 的_scount 是同一个,同一份空间。

不过在类中仍可以通过函数对其进行操作(但是静态成员只能在全局域中定义,即进行初始化)。

静态成员函数: 静态成员函数是没有this指针的, 因此静态成员函数是不能访问 非静态成员变量的。 而静态成员变量定义在静态区,因此仍可以使用静态成员变量。

那么调用时 可以 类名: : 函数名 来调用(当然,前提是该函数是公用的即public的)。那么就可以通过这个函数来返回静态成员变量的值,从而拿到静态成员变量的值(用于当静态成员为private的时候)

对于元素为自定义类型的数组:

Eg

A arr[10];  此处是调用了10此默认构造函数的,每个元素在创建时都调用了其默认构造函数。 因此 对于 1 + 2 + 3 +……+n 的值,可以这样写。

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

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

相关文章

备战面试K8S

备战面试&&K8S Kubernetes关于DockerDocker的优缺点分析 WebAssemblyWebAssembly与Container比较 CtrCrictlCtr和CriCtl的区别 Pod生命周期PodConditions容器状态Pod容器组成生命周期的流程 Kubelet EFK日志采集工具的优缺点 Kubernetes 容器运行接口 Container Runti…

Tensorflow小技巧01:检测本地Tensorflow的版本

前言&#xff1a; 以Pycharm为例&#xff0c;Windwos10系统&#xff0c;检测本地环境的Tensorflow的版本&#xff1a; 1 打开Pycharm窗口 2 在窗口中输入&#xff1a; pythonPython 3.9.5 (tags/v3.9.5:0a7dcbd, May 3 2021, 17:27:52) [MSC v.1928 64 bit (AMD64)] on win…

ChatGPT与Python-GEE融合,遥感云大数据分析、管理与可视化

掌握Earth Engine的实际应用能力&#xff0c;以Python为基础&#xff0c;结合实例讲解平台搭建、影像数据分析、经典应用案例、本地与云端数据管理&#xff0c;以及云端数据论文出版级可视化等技能。 为提高教学质量&#xff0c;将融入ChatGPT 4、Claude Opus、Gemini、文心一…

Centos7.9 脚本一键部署nextcloud,配置Nginx代理Https。

目录 一键安装nextcloud 出现错误TypeError Cannot read properties of undefined (reading ‘writeText‘) 生成自签名SSL证书 编辑Nginx配置文件 启动Nginx 一键安装nextcloud 本脚本参考文章&#xff0c;本文较长建议先看完在操作&#xff01;&#xff01;&#xff01;…

效率工具:企业微信机器人完成脚本工作-异常监控(sql篇)

效率工具&#xff1a;定时完成脚本工作&#xff08;sql篇&#xff09; 背景&#xff1a;elon在公司需要人工查看某些数据是否异常&#xff0c;并发送到指定企业微信群中。 处理步骤&#xff1a; 工具&#xff1a;企业微信中有机器人 可以指定webhook地址嵌入到脚本中&#xf…

C#语法知识之条件分支语句

4、条件分支语句 目录 4、条件分支语句1、条件分支语句 if1、作用2、if语句3、if...else语句4、if...else if...else语句思考1 只需要0~9数字思考2 语句块 2、条件分支语句 switch1、作用2、基本语法3、default可省略4、自定义常量5、贯穿 1、条件分支语句 if 1、作用 //让顺…

Hive进阶(3)----Checkpoint机制(赋图助君理解)

Checkpoint机制 一、Checkpoint机制概念 本机制可以参考《Hadoop权威指南》第十一章&#xff1a; fsimage文件其实是Hadoop文件系统元数据的一个永久性的检查点&#xff0c;其中包含Hadoop文件系统中的所有目录和文件idnode的序列化信息&#xff1b;fsimage包含Hadoop文件系统…

SpringBoot(一)【入门】

前言 1、SpringBoot 快速入门 1.1、SpringBoot 简介 SpringBoot 是用来简化 Spring 应用的初始搭建以及开发过程 首先我们回顾一下 SpringMVC 项目的开发过程&#xff1a; 导入依赖&#xff08;javax.servlet-api 和 spring-webmvc&#xff09;Servlet 容器配置类&#xff…

Pytest精通指南(14)Parametrize之indirect(间接参数)

文章目录 官方概念概念分析官方示例示例分析验证indirect为True但不指定fixture验证indirect为True但不存在fixture 官方概念 概念分析 在pytest的pytest.mark.parametrize装饰器中&#xff0c;indirect参数用于指示是否应该从fixtures中解析参数值&#xff0c;而不是直接使用提…

爆炸之linux-nacos2.0系列集群安装部署

一、环境配置 1、新建磁盘分区 fdisk /dev/vdb 2、创建文件系统 mkfs.xfs /dev/vdb13、创建挂载点&#xff1a; 在 / 目录下创建一个新的目录作为挂载点。/afc 目录 mkdir /afc4、挂载磁盘&#xff1a; 使用 mount 命令将磁盘挂载到新创建的目录。 mount /dev/vdb /afc5、…

Yoshua Bengio独家专访:我不想把大模型未来押注在Scaling Law上,AGI路上要“注意安全”...

导读 漫长的30年间&#xff0c;数度从主流方向的超然出走&#xff0c;是Bengio的制胜秘诀。这种不盲从主流的风格体现在他研究生涯的方方面面。 90年代末期&#xff0c;神经网络被打入冷宫&#xff0c;Bengio的论文多次遭拒&#xff0c;连学生们也开始担心&#xff0c;和他一起…

Vue之v-on事件修饰符的含义及使用

背景&#xff1a;Vue 拆封了一个组件&#xff0c;在组件里面会使用一个方法来改变父组件传过来的值&#xff0c; 但是在子组件里面操作父组件的数据变更&#xff0c;实在比较麻烦&#xff08;因为单向数据流&#xff09;&#xff0c; So 能不能直接在组件上面绑定事件方法呢&…

springSecurity-记住我(Remember me)

一.记住我概述 Remember me(记住我)记住我&#xff0c;当用户发起登录勾选了记住我&#xff0c;在一定的时间内再次登录就不用输入用户名和密码了&#xff0c;即使浏览器退出重新打开也是如此。 二.流程分析 在SpringSecurity中提供RememberMeAuthenticationFilter过滤器来实…

实时动作检测 | 基于Pytorch+YOLOv5+SlowFast实现的视频流实时动作检测算法_支持多目标的跟踪检测

项目应用场景 面向视频流场景的多目标实时动作检测&#xff0c;项目使用 Pytorch YOLOv5 SlowFast 算法实现。 项目效果 项目细节 > 具体参见项目 README.md (1) 创建 Python 开发环境 conda create -n {your_env_name} python3.7.11 conda activate {your_env_name} (2…

npm镜像源的查看和切换

前言 原域名https://registry.npm.taobao.org/ 原来的淘宝镜像已经不行了,当npm去taobao时,会出现一个证书过期的提示. 下面的是最新的地址: 切换到淘宝镜像(最新的地址) #最新地址 淘宝 NPM 镜像站喊你切换新域名啦! npm config set registry https://registry.npmmirror.com…

00_Linux

文章目录 LinuxLinux操作系统的组成Linux的文件系统Linux操作系统中的文件类型Linux操作系统的组织结构 Linux vs WindowsNAT vs 桥接模式 vs 仅主机Linux Shell命令Linux⽂件与⽬录管理相关指令目录文件普通文件文本编辑 用户管理添加用户删除用户用户组管理 文件权限管理权限…

视频教程下载:用ChatGPT快速提升股票投资能力

学完此视频后可以获得&#xff1a; 学习如何使用人工智能/Chatgpt进行基础/快速/高级财务与研究分析 学习如何使用人工智能/Chatgpt对任何公司进行定性投资研究 学习如何使用人工智能/Chatgpt对任何公司进行定量投资研究 学习如何使用人工智能/Chatgpt创建、预测和分析财务…

C语言(二维数组)

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸各位能阅读我的文章&#xff0c;诚请评论指点&#xff0c;关注收藏&#xff0c;欢迎欢迎~~ &#x1f4a5;个人主页&#xff1a;小羊在奋斗 &#x1f4a5;所属专栏&#xff1a;C语言 本系列文章为个人学习笔记&#x…

Mac下brew安装php7.4

这里作者挂了梯子&#xff0c;所以很流畅&#xff01; brew的下载&#xff0c;可参考另外一篇博文&#xff5e;Homebrew 安装与卸载 1、将第三方仓库加入brew brew tap shivammathur/php2、安装指定版本的PHP brew install php7.43、替换Mac自带PHP环境并刷新环境变量 -> …

【uniapp】uniapp返回上一页,并实现刷新界面数据

在uniapp中&#xff0c;经常会有返回上一页的情况&#xff0c;官方提供有 uni.navigateBack 这个api来实现效果&#xff0c;但是此方法返回到上一页之后页面并不会自动刷新&#xff08;不会触发上一页的onLoad()方法&#xff09;。 使用场景 从一个列表界面点击新增按钮&…