[C++ 中]:6.类和对象下(static成员 + explicit +友元函数 + 内部类 + 编译器优化)

(static成员 + explicit +友元函数 + 内部类 + 编译器优化)

  • 一.static 成员:
    • 1.概念引入:
      • 1-1:定义全局变量记录个数?
    • 2.如果有多个类需要分开去记录类对象的个数?
      • 2-1:可不可以声明成员变量解决?
      • 2-2:使用static成员变量:
        • 1.概念:
        • 2.静态成员函数:
        • 3:优点:
    • 3.总结:
    • 4.一个题目:
      • 思路一:
      • 两个问题:
  • 二.explicit:
    • 1.概念引入:
    • 2.概念提升:
      • 支持?
      • 没有缺省值?
    • 3.explicit的作用?
        • 1,概念:
        • 2.使用:
  • 三.友元:
    • 1.友元函数:
      • 总结:
    • 2.友元类:
      • 1.概念:
  • 四:内部类:
    • 1. 概念:
    • 2. 特性:
    • 3.应用:
      • 思路二:
  • 五:拷贝构造时的优化:
    • 1.概念:
    • 2.引入:
      • 情景一:
        • 1.问题?
      • 情景二:
      • 情景三:
      • 情景四:

一.static 成员:

1.概念引入:

请添加图片描述

1-1:定义全局变量记录个数?

1.我们首先想到的方法是定义一个全局的变量去记录创建类对象的个数,我们定义一个count去在对象构造的时候进行++。
在这里插入图片描述

2.经过下面的图片可以看到在全局count被多次定义所以我们可以通过命名空间把count这个全局给封装一下!
请添加图片描述

2.如果有多个类需要分开去记录类对象的个数?

2-1:可不可以声明成员变量解决?

我们可以声明一个成员变量去在构造的过程中去记录个数创建类对象的个i数?
答:是不可以的,因为每一个成员变量都被分配了一个空间。不可能产生去记录个数的作用!

2-2:使用static成员变量:

1.概念:

1.static成员变量是声明在类中的,是在全局初始化(定义)的。
2.静态成员为所有类对象所共享,不属于某个具体的对象,存放在静态区
请添加图片描述

2.我们想要获得在类里面声明的_count ,可以解除类域和访问限定符的限制做到可以直接打印个数构造的个数:
请添加图片描述

3.我们加上一个域和访问限定都是防止外面可以随便访问类的成员进行随意的修改,所以这里可以考虑使用类的成员函数去获取通过类和访问限定修饰的_count
4.正常寻找数据是向上寻找,在当前函数域中找再到全局中去找,如果不加域访问限定符,正常是不会到类中寻找。这也是命名空间存在的意义!

1.使用用类的成员函数我们是需要一个类的对象的,不然调用不到这个成员函数:

请添加图片描述

2.匿名代码优化:

请添加图片描述

2.静态成员函数:

1.我们上面的操作都是通过创建一个对象去通过创的对象进行函数的调用获取个数并且还需要减去1.因为多创建了一个对象用来计数。
2.静态成员函数是没有指针的,只需要进入类域就可以访问到静态成员函数。这个时候静态成员函数是全局的函数但是被这个类所占有需要通过域访问限定符进行访问
3.静态成员函数不可以访问非静态的成员变量因为静态成员函数是没有this指针的!

请添加图片描述
请添加图片描述

3:优点:

通过静态成员函数和静态成员变量,可以在完美的计算个数的同时不会影响类原来的任何操作。

3.总结:

  1. 静态成员为所有类对象所共享,不属于某个具体的对象,存放在静态区
  2. 静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明
  3. 类静态成员即可用 类名::静态成员 或者 对象.静态成员 来访问
  4. 静态成员函数没有隐藏的this指针,不能访问任何非静态成员
  5. 静态成员也是类的成员,受public、protected、private 访问限定符的限制
    6.静态成员函数和静态成员变量本质都是全局的只是受到类的限制。

4.一个题目:

请添加图片描述
题目链接

思路一:

我们看一下这个题目基本上所有通过运算的方法都被限制完全了没有什么方法可以解决了,但是我们经过上面的学习是不是可以通过构造N次去模拟实现循环N次再通过静态成员函数和静态成员变量解决这个问题呢?

class A{
public:
    A()
    {
        _sum+=_i;
        _i++;
    }
    static int Get_Sum()
    {
        return _sum;
    }
private:
    static int _i;
    static int _sum;
};

int A::_i=1;
int A::_sum=0;

class Solution {
public:
    int Sum_Solution(int n) {
        A arr[n];
        return A::Get_Sum();      
    }
};

两个问题:

  1. 静态成员函数可以调用非静态成员函数吗?
    答:不可以: 静态成员函数没有this指针不可以调用非静态成员函数并且不可以调用非静态成员变量。

  2. 非静态成员函数可以调用类的静态成员函数吗?
    答:可以 :静态成员函数只是收到类域的限制我们想要使用静态成员函数需要指定类域。

二.explicit:

1.概念引入:

请添加图片描述

我们观察上面的代码,为什么发生隐式类型转换呢?

答:关于内置类型不相同的之间可以发生隐式类型转换。我们这里是内置类型和自定义类型之间发生的隐式类型转换。是因为有单参数的构造函数支持发生了隐式类型的转换!

2.概念提升:

既然存在支持单参数的构造函数那么存不存在支持多参数的构造函数呢?
在这里插入图片描述

支持?

我们发现其实是支持多参数的隐式类型转换,但是我们month和day都有缺省值在这个地方本质还是一个单构造函数支持的隐式类型转换!

没有缺省值?

C++11 支持进行列表初始化!

请添加图片描述
请添加图片描述

3.explicit的作用?

1,概念:

1.使用:加在构造函数函数名之前可以阻止上面的这个隐式类型转换的发生!
2.作用:使用explicit相当于把这个构造函数给标记为了显示的构造函数这个构造函数就不会支持隐式类型的转换了
3.强制类型转换是管不了的!

在这里插入图片描述
在这里插入图片描述

2.使用:

通过模板创建了一个Date类型的一个链表,调用push_back 函数。三个方法可以进行尾插!

1.方法一:正常创建一个对象去进行插入。
2.方法二:通过匿名对象进行插入。
3.方法三:通过隐式类型转换支持的一个尾插数据:
4.在大多数情况下都是允许隐式类型转换的发生的,在少部分情况下不允许隐式类型转换发生的!

请添加图片描述

三.友元:

1.友元函数:

问题:现在尝试去重载operator<<,然后发现没办法将operator<<重载成成员函数因为cout的输出流对象和隐含的this指针在抢占第一个参数的位置 this指针默认是第一个参数也就是左操作数了。但是实际使用中cout需要是第一个形参对象,才能正常使用。所以要将operator<<重载成全局函数。但又会导致类外没办法访问成员,此时就需要友元来解决。operator>>同理。

总结:

友元函数可访问类的私有和保护成员,但不是类的成员函数
友元函数不能用const修饰
友元函数可以在类定义的任何地方声明,不受类访问限定符限制
一个函数可以是多个类的友元函数
友元函数的调用与普通函数的调用原理相同

2.友元类:

1.概念:

友元类的成员函数都可以是另一个类的友元函数,并且可以访问非公有的成员变量。

友元关系是单向的,不具有交换性:
下面这个例子:B是A的友元,说明A把B当成朋友。B就可以随便使用A的成员函数和访问A类的私有。但是B不一定把A当作朋友所以A不可以随便访问B的成员函数或者私有成员变量。

友元关系不能传递:
如果C是B的友元, B是A的友元,则不能说明C是A的友元。

友元关系不能继承:

在这里插入图片描述
请添加图片描述
请添加图片描述

四:内部类:

1. 概念:

如果一个类定义在另一个类的内部,这个【内部】的类就叫做【内部类】。内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去访问内部类的成员。外部类对内部类没有任何优越的访问权限。

注意:内部类就是外部类的友元类,参见友元类的定义,内部类可以通过外部类的对象参数来访问外部类中的所有成员。但是外部类不是内部类的友元。

2. 特性:

  1. 内部类可以定义在外部类的public、protected、private都是可以的。
  2. 注意内部类可以直接访问外部类中的static成员,不需要外部类的对象/类名。
  3. sizeof(外部类)=外部类,和内部类没有任何关系。
  4. A和B的关系,他们都是一个普通类。只是关系比较密切B受到A的访问限定符的限制。B作为A的友元可以随便访问成员函数或者成员变量。
  5. 本质:多了一个封装+多了一个友元!
    请添加图片描述

3.应用:

请添加图片描述

题目链接

思路二:

1.思路一有可能出现问题在solution创建新的对象导致数值错误我们使用下面的优化方法就不可能出现这样的问题!

2.可不可以把用来构造记录个数的类作为solution的内部类定义solution的私有为_i _sum,通过内部类是外部类的友元操作到的外部类的成员变量。外部类的成员函数自然可以访问到静态成员变量。

class Solution {
public:
    class A{
    public:
        A()
        {
            _sum+=_i;
            _i++;
        }
        static int Get_Sum()
        {
            return _sum;
        }
    };

    int Sum_Solution(int n) {
        A arr[n];
        return A::Get_Sum();      
    }
    
private:
    static int _i;
    static int _sum;
};

int Solution::_i=1;
int Solution::_sum=0;

五:拷贝构造时的优化:

1.概念:

在传参和传返回值的过程中,一般编译器会做一些优化,减少对象的拷贝,这个在一些场景下还是非常有用的。

请添加图片描述

2.引入:

情景一:

在这里插入图片描述

1.问题?

因为理论上发生了隐式类型的转换所以会发生一次构造和一次拷贝构造,但是根据打印结果显示只发生了一次构造和一次析构?

答:因为编译器进行了优化,条件是必须在一行进行构造+拷贝构造!

情景二:

进行构造和拷贝构造不在同一行,通过代码执行发现编译器没有对这样的操作进行优化!

请添加图片描述

情景三:

补充整形值是具有常性的所以构造函数的参数是const类型的参数!

在这里插入图片描述

情景四:

拷贝构造+拷贝构造—》拷贝构造

请添加图片描述

请添加图片描述
请添加图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LangChain之关于RetrievalQA input_variables 的定义与使用

最近在使用LangChain来做一个LLMs和KBs结合的小Demo玩玩&#xff0c;也就是RAG&#xff08;Retrieval Augmented Generation&#xff09;。 这部分的内容其实在LangChain的官网已经给出了流程图。 我这里就直接偷懒了&#xff0c;准备对Webui的项目进行复刻练习&#xff0c;那么…

HTML的初步学习

HTML HTML 描述网页的骨架, 标签化的语言. HTML 的执行是浏览器的工作,浏览器会解析 html 的内容,根据里面的代码,往页面上放东西,浏览器的工作归根结底,还是以汇编的形式在CPU上执行. 浏览器对于html语法格式的检查没有很严格,即使你写的代码有一些不合规范之处,浏览器也会尽可…

GIS开发入门,TopoJSON格式是什么?TopoJSON格式与GeoJSON格式有什么不同?

TopoJSON介绍 TopoJSON是一种几何拓扑结构的地理数据格式,它使用拓扑结构来表示地理对象,可以更有效地压缩和转移数据,从而加快数据加载速度。 TopoJSON格式构成 TopoJSON文件由三部分组成,transform、objects和arcs组成。transform描述了变换参数; objects描述地理实体…

NCV7721D2R2G一款完全保护的双半桥驱动器 专为汽车工业运动控制解决方案

NCV7721D2R2G是一款完全保护的双半桥驱动器&#xff0c;专为汽车和工业运动控制应用而设计。两个半桥驱动器具有独立控制。这允许高侧、低侧和H桥控制。H桥控制提供正向、反向、制动和高阻抗状态。驱动器通过逻辑电平输入进行控制。 特性&#xff1a; 1.睡眠模式下的超低静态电…

生成无损压缩png和有损压缩png的做法

作者:朱金灿 来源:clever101的专栏 为什么大多数人学不会人工智能编程?>>> png是一种常用的图像格式。png一般为无损压缩,但是可以是有损压缩的。 下图都是100x100的png图像,一个是无损压缩,一个是有损压缩。 看着效果基本一样,但是它们的大小相差很大,无损…

WPF布局与控件分类

Refer&#xff1a;WPF从假入门到真的入门 - 知乎 (zhihu.com) Refer&#xff1a;WPF从假入门到真的入门 - 知乎 (zhihu.com) https://www.zhihu.com/column/c_1397867519101755392 https://blog.csdn.net/qq_44034384/article/details/106154954 https://www.cnblogs.com/mq0…

k8s之service五种负载均衡byte的区别

1&#xff0c;什么是Service&#xff1f; 1.1 Service的概念​ 在k8s中&#xff0c;service 是一个固定接入层&#xff0c;客户端可以通过访问 service 的 ip 和端口访问到 service 关联的后端pod&#xff0c;这个 service 工作依赖于在 kubernetes 集群之上部署的一个附件&a…

【黑马程序员】SpringCloud——Eureka

文章目录 前言一、提供者与消费者1. 服务调用关系 二、远程调用的问题三、eureka 原理分析1. eureka 的作用 四、Eureka 案例1. 搭建 eureka 服务1. 服务注册1.1 注册 user-service1.2 启动 user-service3. order-service 完成服务注册 3. 服务发现1. 在 order-service 完成服务…

把枯燥的PDF文档转换为翻页电子书,一键上传搞定

PDF是我们工作生活中比较常用的文档格式之一&#xff0c;由于PDF文件可以离线观看&#xff0c;所以通常都是静态的&#xff0c;有时候密密麻麻的文字看得很是头晕眼花&#xff0c;这使得阅读体验变得单调乏味。 为了解决这个问题 &#xff0c; 我们推荐使用FLBOOK &#xff0c…

JS逆向爬虫---响应结果加密⑤【token参数加密与DES解密】

https://spa7.scrape.center/ 文本数据 数据内嵌在js内,普通合理请求即可获取 图片 位于固定接口 类似https://spa7.scrape.center/img/durant.png 固定url名称 Token 参数确定 base64Name > base64编码后的中文名称 nodejs 代码 //导入crypto-js模块 var CryptoJS…

【AntDesign】Docker部署

docker部署是主流的部署方式&#xff0c;极大的方便了开发部署环境&#xff0c;保持了环境的统一&#xff0c;也是实现自动化部署的前提。 1 项目的目录结构 dist: 使用build打包命令&#xff0c;生成的打包目录 npm run build : 打包项目命令 docker: 存放docker容器需要修改…

Elasticsearch:ES|QL 中的数据丰富

在之前的文章 “Elasticsearch&#xff1a;ES|QL 查询语言简介”&#xff0c;我有介绍 ES|QL 的 ENRICH 处理命令。ES|QL ENRICH 处理命令在查询时将来自一个或多个源索引的数据与 Elasticsearch 丰富索引中找到的字段值组合相结合。这个有点类似于关系数据库查询中所使用的 jo…

【Proteus仿真】【Arduino单片机】OLED液晶显示

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真Arduino单片机控制器&#xff0c;使用IIC OLED液晶等。 主要功能&#xff1a; 系统运行后&#xff0c;OLED液晶显示各种图形、字符、图像。 二、软件设计 /* 作者&#xff1a;嗨小…

6个机器学习可解释性框架

1、SHAP SHapley Additive explanation (SHAP)是一种解释任何机器学习模型输出的博弈论方法。它利用博弈论中的经典Shapley值及其相关扩展将最优信贷分配与局部解释联系起来. 举例&#xff1a;基于随机森林模型的心脏病患者预测分类 数据集中每个特征对模型预测的贡献由Shap…

工业CT 三维重建 及分割

目录 工业CT介绍 工业CT主要应用于以下领域&#xff1a; CT三维重建软件&#xff1a; 效果&#xff1a; 工业CT介绍 工业CT设备是基于线阵探测器的断层扫描技术&#xff0c;是一种常用的无损检测技术&#xff0c;用于获取物体内部的准确三维结构信息。它通过X射线的投射和接…

计算机网络学习笔记(五):运输层(待更新)

5.1 概述 5.1.1 TCP协议的应用场景 TCP为应用层协议提供可靠传输&#xff0c;发送端按顺序发送&#xff0c;接收端按顺序接收&#xff0c;其间发送丢包、乱序&#xff0c;TCP负责重传和排序。下面是TCP的应用场景。 多次交互&#xff1a;客户端程序和服务端程序需要多次交互才…

SQL必知会(二)-SQL查询篇(2)-排序检索数据

第3课、排序检索数据 排序数据 OEDER BY&#xff1a;排序 进行排序 1&#xff09;按单个列排序 需求&#xff1a; 以 prod_name 字段按照字母顺序排序 SELECT prod_name FROM Products ORDER BY prod_name; -- 以 prod_name 列按照字母顺序排序输出结果&#xff1a; 2&…

高等数学教材重难点题型总结(一)函数与极限

强化阶段的另一个专题&#xff0c;本专题主要总结高数课本上的经典例题与课后题&#xff0c;尤其一部分加*标的题目&#xff0c;对于冲击高分的同学来说&#xff0c;必须熟练掌握。 &#xff08;蓝色代表难点&#xff0c;红色代表重点&#xff0c;紫色代表重难点&#xff09; …

软文发布如何选择对应的媒体

企业做软文推广第一步&#xff0c;就是选择合适的媒体进行投放&#xff0c;然而许多企业不知道如何选择合适的媒体导致推广工作十分被动&#xff0c;无法取得效果&#xff0c;今天媒介盒子就来和大家分享&#xff0c;企业应该如何选择对应的媒体。 一、 媒体类型 根据软文类型…

【Python】python获取本机IP的两种方式

1.使用专用网络 通过进入网站&#xff1a;http://myip.ipip.net获取本机ip地址 代码实现&#xff1a; import requests res requests.get(http://myip.ipip.net, timeout5).text print(res) 也可以在终端cmd中用如下代码实现; curl http://myip.ipip.net 2.使用自带的socke…
最新文章