C++类和对象(5)static修饰的静态成员变量函数

1.静态成员函数和静态成员变量的引入

(1)我们通过以下面的这个例子逐步引出静态的成员变量和成员函数:

我们自己定义一个类,使用这个类创建对象,我们应该如何判断在这个程序执行的过程中,创建了多少个对象,有几个对象是正在使用的。

 (2)上面的这个代码就可以进行判断正在使用的对象的个数和创建的对象的个数,我们是定义了一个n用来记录创建的对象的个数,我们定义了一个m用来记录正在使用的对象个数;

(3)我们在这个程序里面是写了4个函数,3个是默认的函数,1个就是我们自己定义的func函数,当执行默认构造函数和拷贝函数的时候,就让nm都加加,当执行析构函数的时候,就让m--,说明已经有一个对象被销毁了;最后再打印输出nm的数值;

(4)在这个过程中,我们有3组打印输出的结果,我们知道 m打印的结果一直都是2,说明正在使用的对象就是2个,n打印的结果在变化,说明一直有对象被创建;

(5)第一次的打印结果两个2很容易理解, 创建2个对象,执行默认构造函数,正在使用的对象个数是2,所以打印结果是两个2;

(6)A()这个我们之前提到过,这个就是一个匿名的对象,我们只需要记住匿名对象在进行创建的时候,在外观上面和默认的构造函数长的是一样的,所以这个时候创建的对象的个数除了前面的a1,a2还有我们现在的匿名对象A(),就是创建了3个对象,但是匿名对象的生命周期就在创建的那一行,所以在执行cout的时候,这个匿名对象的生命周期已经结束了,并不是正在使用的,所以m的值还是2;

(7)当我们调用func函数的时候,打印的结果显示n=5说明这个时候创建了5个对象,为什么会比第二次打印时候的3又多了2个呢?因为我们调用了func这个函数,a1这个实参传递给aa这个形参执行拷贝构造函数,这个时候需要创建对象,而且返回的时候,因为是传值返回,我们需要创建一个对象作为临时变量,所以又要创建一个对象,综上所述,一共是创建了5个对象;

(8)如果在func函数里面,我们是传引用返回,这个时候就不会生成这个临时的对象,这个时候的n就是4;如果我们使用传引用返回而且形参也是引用的,这个时候就不会执行拷贝构造函数,这个时候n=3;当然因为这个地方的aa这个返回值是出了作用域就会销毁的,并不符合传引用返回的条件,我们在这里只是说明问题,传引用返回实际上是不规范的;

这个过程我们好像并没有使用到静态的成员变量和成员函数,下面我们们将在这个题目的基础上面引入

2.为什么会存在静态的成员变量和成员函数

(1)上面的写法是有缺陷的,什么缺陷呢?

我们首先要理解的就是C++的一个很重要的特点就是封装性,但是这个里面我们定义的n和m都是全局的变量,很容易被修改破坏,因此我们可以把这两个变量放到类的里面去;

(2)放到类的里面之后,我们就要知道这个nm都是对象的,就是我们创建的任何一个对象都有n和m,现在我们想要这个n和m属于这个类,就要在前面加上static;

这个时候,我们在nm这两个成员变量的前面加上static之后,这两个成员变量就是静态成员变量,属于整个类了,而不是某一个单独的对象,这个时候我们会发现在等号的位置有报错;

这个就说明静态成员变量就不可以给缺省值了,为什么会这样?

因为我们在这个地方给的缺省值是传递给了初始化列表的,初始化列表是对对象进行初始化的,但是我们这里的静态成员变量是属于这个类的,不会走初始化列表的,所以就不应该给缺省值;

(3) 我们在类里面声明静态的成员变量,我们还是要进行定义的,我们可以在外面定义进行初始化的操作;因为这个时候静态的成员变量属于整个类域,所以我们在类外面定义的时候加上访问操作符;

(4)声明和定义完成之后,我们就可以进行打印输出成员变量的值,例如这里的A::m,a1.m都是可以访问到这些公有的成员变量的;但是我们不能直接打印nm这种,因为现在这个n和m已经在类域里面了,默认情况下我们找的时候只会在全局找,不会跑到类域里面去找的;

这个就相当于是有一个围墙,我们在打印的时候,就要看在全局里面是否存在这个变量,A::这种方式相当于是突破了围墙的限制,允许编译器到类域的里面去找,a1.这个也是可以突破围墙的,这个直接打印就不行;

(5) 我们上面还有一个实例,就是定义了一个A类的指针并且初始化为nullptr,我们使用ptr->n这样的方式也是可以突破围墙的限制,访问到静态的成员变量,并不会报错;

(6)上面的所有讨论都是建立在我们的静态成员变量都是public的,如果他们是private的,就都会报错,我们要想访问private这个里面的静态的成员变量,就需要使用和静态的成员变量相互对应的静态的成员函数;

(7)在private情况下面,我们可以在类里面定义getm这样的函数让函数的返回值是我们想要的n和m,但是如果我们是定义的匿名对象呢?

我们也可以使用A().print()的方式进行匿名对象函数的调用,但是这个会影响我们的判断,因为这个匿名对象调用print函数会创建一个新的对象,但是这个对象的创建是没有必要的;

(8)这个时候我们就可以在函数的前面加上static这样的话函数就成为了静态的成员函数;

静态的成员函数的特点是没有this指针,我们之前的那些普通函数有this指针(就是我们使用A这个类创建一个对象a1,我们使用a1.print()就可以调用这个函数,这个函数里面是有this指针接受这个传递过来的对象的);

现在的静态的成员函数,我们可以直接使用A::print()进行匿名对象的函数的调用,但是匿名函数里面不可以调用非静态的变量,因为非静态的变量的调用需要这个函数有this指针,但是静态的成员函数没有this指针。

(9)静态成员函数的限制就是不能访问非静态的成员变量,为什么非静态的需要this指针呢?

因为我们知道静态的成员变量是在类里面的,属于类域,但是非静态的就是属于某个对象的,我们要想使用这个非静态的变量,我们就要适用对象进行使用,但是有对象就有this指针 ,相当于我们的非静态的变量需要this但是静态成员函数没this所以不可在静态函数里面使用非静态的变量。

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

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

相关文章

深度解析Nginx:高性能Web服务器的奥秘(上)

🐇明明跟你说过:个人主页 🏅个人专栏:《洞察之眼:ELK监控与可视化》🏅 🔖行路有良友,便是天堂🔖 目录 一、前言 1、Nginx概述 2、Nginx的历史与发展 3、Nginx的…

软件全套资料梳理(需求、开发、实施、运维、安全、测试、交付、认证、评审、投标等)

软件全套精华资料包清单部分文件列表: 工作安排任务书,可行性分析报告,立项申请审批表,产品需求规格说明书,需求调研计划,用户需求调查单,用户需求说明书,概要设计说明书&#xff0c…

根据docker部署nginx并且实现https

目录 一、Docker中启用HTTPS有几个重要的原因 二、https介绍 三、https过程 四、安装docker-20.10.18 五、如何获取证书 通过阿里云获取证书 六、docker部署nginx并且实现https 6.1准备证书 6.2准备nginx.conf 和 index.html文件 6.3生成容器 6.4浏览器验证证书 一、…

2024年4月24日华为春招实习试题【三题】-题目+题解+在线评测,2024.4.24,华为机试

2024年4月24日华为春招实习试题【三题】-题目题解在线评测,2024.4.24,华为机试 🏩题目一描述:输入格式输出格式样例1样例2样例3数据范围解题思路一:dfs解题思路二:直接二分查找哇!解题思路三&am…

MySQL数据库的初始化(创建库、创建表、向数据库添加测试数据)

MySQL数据库的初始化(创建库、创建表、向数据库添加测试数据) MySQL数据库简介MySQL创建一个新的数据库MySQL创建一张新的数据表简单(设置)表复杂(设置)表 填充测试数据SQL语句mysql>模式下输入的每句sq…

技术爱好者必看:如何用AI问答API彻底改变用户体验!

AI 问答 API 对接说明 我们知道,市面上一些问答 API 的对接还是相对没那么容易的,比如说 OpenAI 的 Chat Completions API,它有一个 messages 字段,如果要完成连续对话,需要我们把所有的上下文历史全部传递&#xff0…

FreeRtos内核源码分析(九)——协程

目录 一、协程简介 二、协程工作机制 2.1 协程控制块结构 2.2 协程管理方式 2.3 协程调度方式 2.4 协程通信机制 三、协程状态及状态切换 3.1 协程状态 3.2 状态切换 四、协程创建 五、协程调度分析 5.1 源码分析 5.2 逻辑图分析 六、协程通信 6.1 协程发送消息…

如何清除DNS缓存,刷新DNS

大家在使用域名访问服务器的时候,经常会遇到一个问题,同一个局域网里的两台电脑,一台可以访问而另一台不行。这是为什么呢?这里我要和大家说下DNS缓存的问题,顾名思义,每台电脑都有DNS缓存,在域…

ElasticSearch 8.X 源码导入idea并配置环境启动调试(mac环境)

主要是用于自己记录配置流程 环境 IntelliJ IDEA 2024.1.1 (Community Edition) jdk17(可以安装jenv管理) macos 14.4.1 gradle 8.5 资源准备 先在官网下载elasticsearch源码(GitHub - elastic/elasticsearch: Free and Open, Distrib…

webservice和TCP类型接口测试

1.webservice类型接口 1.1.webservice类型接口介绍 Web服务(WebService)是一种基于网络的应用程序接口(API),可通过网络来进行通信和交互。它们使用标准化的协议和格式来进行通信,最常见的是使用XML&#…

AI图书推荐:利用生成式AI实现业务流程超自动化

《利用生成式AI实现业务流程超自动化》(Hyperautomation with Generative AI)这本书探索了广泛的用例和示例,展示了超自动化在不同行业、领域和特定部门的多样化应用, 让您熟悉UiPath、Automation Anywhere和IBM等流行工具和平台&…

LeetCode 105.从前序与中序遍历序列构造二叉树

LeetCode 105.从前序与中序遍历序列构造二叉树 1、题目 题目链接:105. 从前序与中序遍历序列构造二叉树 给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树…

MVCC 详解

介绍 MVCC,全称 Multi-Version Concurrency Control,即多版本并发控制 MVCC的目的主要是为了提高数据库并发性能,用更好的方式去处理读-写冲突,做到即使有读写冲突时,也能做到不加锁。 这里的多版本指的是数据库中同时…

【GO】go语言中的HTTP标准库 - http编程

上一节已经学习了HTTP的基础知识,本章将学习关于go语言的HTTP编程,最重要的是掌握 net/http 包的用法,以及如何自己编写一个简单的Web服务端,通过客户端访问Server端等。 编写简单的Web 服务器 http.ListenAndServe 启动 Http S…

Unity开发中导弹路径散射的原理与实现

Unity开发中导弹路径散射的原理与实现 前言逻辑原理代码实现导弹自身脚本外部控制脚本 应用效果结语 前言 前面我们学习了导弹的追踪的效果,但是在动画或游戏中,我们经常可以看到导弹发射后的弹道是不规则的,扭扭曲曲的飞行,然后击…

Reactor Netty 其他-响应式编程-018

🤗 ApiHug {Postman|Swagger|Api...} 快↑ 准√ 省↓ GitHub - apihug/apihug.com: All abou the Apihug apihug.com: 有爱,有温度,有质量,有信任ApiHug - API design Copilot - IntelliJ IDEs Plugin | Marketplace The Nex…

vue3点击添加小狗图片,vue3拆分脚本

我悄悄蒙上你的眼睛 模板和样式 <template><div class"XueXi_Hooks"><img v-for"(dog, index) in dog1List" :src"dog" :key"index" /><button click"addDog1">点我添加狗1</button><hr …

每日一题9:Pandas-填充缺失值

一、每日一题 DataFrame products --------------------- | Column Name | Type | --------------------- | name | object | | quantity | int | | price | int | ---------------------编写一个解决方案&#xff0c;在 quantity 列中将缺失的值 编…

Leetcode 剑指 Offer II 077.排序链表

题目难度: 中等 原题链接 今天继续更新 Leetcode 的剑指 Offer&#xff08;专项突击版&#xff09;系列, 大家在公众号 算法精选 里回复 剑指offer2 就能看到该系列当前连载的所有文章了, 记得关注哦~ 题目描述 给定链表的头结点 head &#xff0c;请将其按 升序 排列并返回 排…

Xilinx 千兆以太网TEMAC IP核 MDIO 配置及物理接口

基于AXI4-Lite接口可以访问MDIO(Management Data Input/Output)接口&#xff0c;而MDIO接口连接MAC外部的PHY芯片&#xff0c;用户可通过AXI4-Lite接口实现对PHY芯片的配置。 1 MDIO接口简介 开放系统互连模型OSI的最低两层分别是数据链路层和物理层&#xff0c;数据链路层的…