[C++从入门到精通] 9.inline、const、mutable、this和static

  • 📢博客主页:https://loewen.blog.csdn.net
  • 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
  • 📢本文由 丶布布原创,首发于 CSDN,转载注明出处🙉
  • 📢现在的付出,都会是一种沉淀,只为让你成为更好的人✨

文章预览:

      • 一. 特殊的成员函数inline
      • 二. 成员函数末尾的const
      • 三. mutable
      • 四. 返回自身对象的引用_this
      • 五. static成员


一. 特殊的成员函数inline

假设我们不在头文件中声明、源文件中定义函数了,而是全部放在头文件中来实现:

class Time
{
public:explicit Time(int tmphour);  int Hour;public:void addHour(int tempHour){Hour += tempHour;}	
};

这种直接在类的定义中实现的函数,会被系统当做内联函数inline来处理,其他相关的知识点可以参考我们之前的讲解。


二. 成员函数末尾的const

成员函数后面增加一个const的限定词后也被称为常量成员函数,其特性与用法如下:

特性:

1.不但要在成员函数的声明后增加const,也要在成员函数的定义中增加const
2.非成员函数不允许使用const修饰符
3.const成员函数既能被const类型对象调用也能被非const类型对象调用

作用:

const成员函数被限定:不能在函数中修改关于类的任何状态,包括其各种成员变量的值

举例:

//.h
class Time
{
public:explicit Time(int tmphour);  explicit Time();  int Hour;public:void addHour(int tempHour) const;};
//.cpp
void addHour(int tempHour) const
{Hour = tempHour;  //报错:表达式必须是可修改的左值(因为const定义的成员函数,其内的成员变量值不能被修改)
}

此外,const成员函数也是个万人迷,既能被const类型对象调用也能被非const类型对象调用;非const成员函数只能被非const类型对象调用。

public:void addHour(int tempHour) const;void addMinute(int tempMinute);

在这里插入图片描述


三. mutable

问题:

如何修改const修饰的常量成员函数中的成员变量?

前面我们说过常量成员函数中的成员变量不可以进行修改,这里有人会想了,那我直接取消常量成员函数后面的const修饰,将其变成普通成员函数,是不是就可以正常修改其内的成员变量了。没错,这样是可以修改了,但是我们不要忘了:

  • const成员函数既能被const类型对象调用也能被非const类型对象调用
  • const成员函数(普通成员函数)只能被非const类型对象调用

这就导致一个问题,就是如果之前代码中是使用const类型对象调用的常量成员函数,这时将常量成员函数变成普通成员函数后,我们也必须将调用其的const类型对象改为非const类型对象后才能正常调用修改后的普通成员函数。将原本const修饰的类对象取消掉,这违背了程序设计的初衷——不想让这个类对象修改成员变量的值。

定义:

为了解决上述的问题,我们引入了mutable的概念来突破const的限制,mutable(不稳定,容易改变的意思),const的反义词。

mutable修饰的成员变量,表示这个成员变量永远处于可以被修改的状态,即便是在const结尾的常量成员函数中。

举例:

class Time
{
public:mutable int Hour;public:void addHour(int tempHour) const;
};
void Time::addHour(int tempHour) const
{Hour = tempHour;  //因为Hour是被mutable修饰的,这里即使是在常量成员函数addHour中,仍然可以被修改。
}

四. 返回自身对象的引用_this

class Time
{
public:int Hour = 50;
public:Time &addHour(int tempHour);
};
Time &Time::addHour(int tempHour)
{Hour += tempHour;return *this;  //把对象自己给返回去了
}int main()
{Time myTime;myTime.addHour(2);
}

Time对象myTime的地址:0x001df720

在这里插入图片描述
返回的this指针地址仍为:0x001df720

在这里插入图片描述

结论: 说明this是一个指向自身类对象(myTime)的指针。

  • return *this返回的是当前对象的克隆或者本身(若返回类型为Time,则是克隆;若返回类型为Time&,则是本身。本文举例是后者)。
  • return this 返回当前对象的地址(指向当前对象的指针)

如何理解这个this?

当我们在程序中调用成员函数/成员变量时,编译器负责把这个对象的地址(&myTime)传递给成员函数中一个隐藏的this形参

即:

//我们写的:T
ime &Time::addHour(int tempHour){}//实际上的
Time &Time::addHour(Time *this, int tempHour){}
Time myTime;//我们写的:
myTime.addHour(2);  //实际上的
myTime.addHour(&myTime, 2);  //调用时,编译器会把myTime的地址传递给成员函数隐藏的`this`形参

这也解释了一个问题:为什么在成员函数中,不需要调用就可以直接使用成员变量?

Time &Time::addHour(int tempHour)
{//程序员角度:Hour += tempHour;  //成员变量Hour	//系统的角度:this->Hour += tempHour;  
}

因为在系统角度看来,任何对类成员(Hour)的直接访问,都被系统看做是通过this做隐式调用的(this->Hour)。

this的相关特性:

  • this指针只能在成员函数中使用,静态函数或全局函数等是不存在this指针的。
  • 在普通成员函数中,this是一个指向非const对象的const指针。
    假设类是Time,那么this的实际定义是Time *const this,即this指针只能指向当前类对象,不能在指向其他类的对象(const后置)。
  • const成员函数中(void Time::addHour(int tempHour) const;), this是一个指向const对象的const指针。
    假设类是Time,那么this的实际定义是const Time *const this,不但this不能在指向其他类对象,而且this指向的自身类对象的成员变量值也不能更改。

五. static成员

参考我的另一篇文章:[C++] static静态成员变量/函数的用法


下雨天,最惬意的事莫过于躺在床上静静听雨,雨中入眠,连梦里也长出青苔。

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

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

相关文章

Ansible专栏目录

我的博客:www.itwk.cc 希望能够给大家带来帮助! 文章目录 1、什么是Ansible?Ansible 简介及核心概念详解 :https://blog.csdn.net/qq_34185638/article/details/131079320 2、Ansible Inventory 主机清单的作用、使用方法及示例…

Day 75:通用BP神经网络 (2. 单层实现)

代码: package dl;import java.util.Arrays; import java.util.Random;/*** Ann layer.*/ public class AnnLayer {/*** The number of input.*/int numInput;/*** The number of output.*/int numOutput;/*** The learning rate.*/double learningRate;/*** The m…

极海APM32F003F6P6烧写问题解决记录

工作中遇到的,折腾了好久,因为电脑重装过一遍系统,软件也都重新安装了,所以不知道之前的配置是什么,旧项目代码编译没问题,烧写时疯狂报错,用的是JLink。 keil版本v5.14 win10版本 JLink版本…

08_Vue3 自定义hook函数

目录 自定义hook函数 例如: src下新建文件夹 hooks 创建js文件,文件名为 usePoint.js 在 App.vue 中 Demo.vue 组件中 Test.vue 组件中 自定义hook函数 什么是 hook ?——本质是一个函数,把 setup 函数中使用的 Composition API 进行…

class version 61 java version 17.0.4

class version (javap -verbose xxxx.class)_spencer_tseng的博客-CSDN博客

基于EEGLAB的ICA分析

目录 1.ICA原理 2.ICA的实现 3.ICA成分识别 4.ICLabel识别并去除伪迹 5.ICA成分识别练习 1.ICA原理 得到的每一个地形图,实际上就是它的权重谱。 投射:根据原成分恢复原始信号。 选择性投射:去伪。 2.ICA的实现 extended,1&…

聊聊企业数据安全那些事~

保护企业数据安全的重要性与方法 随着信息技术的快速发展,企业数据的安全性变得越来越重要。在数字化时代,企业的核心业务和关键信息都存储在电脑系统中,一旦遭受到数据泄露、黑客攻击或恶意软件感染,将可能对企业造成严重的损害…

原型链污染是什么

__proto__ 一个Foo类实例化出来的foo对象,可以通过foo.__proto__属性来访问Foo类的原型,也就是说: foo.__proto__ Foo.prototype 对象 构造函数 所以,总结一下: prototype是一个类的属性,所有…

24考研数据结构-图的基本操作

目录 6.6. 图的基本操作1. Adjacent(G,x,y)边的存在2. Neighbors(G,x):列出图G中与结点x邻接的边3. InsertVertex(G,x):在图G中插入顶点x4. DeleteVertex(G,x):从图G中删除顶点x5. AddEdge(G,x,y):若无向边(x,y)或有向边<x,y>不存在&#xff0c;则向图G中添加该边。6. Fi…

智能视觉新时代:探索Intewell-Hyper II在机器视觉芯片检测中的独特魅力

随着科技的不断进步&#xff0c;芯片制造业正在经历前所未有的快速发展。为了确保芯片的品质和可靠性&#xff0c;机械视觉芯片检测技术逐渐成为行业内的重要环节。作为机器视觉领域的重要部分&#xff0c;Intewell操作系统在打造高效、精确的检测方案方面发挥着关键作用。 基…

GraphGT: Machine Learning Datasets for Graph Generation and Transformation

一、文章来源 > Du Y, Wang S, Guo X, et al. Graphgt: Machine learning datasets for graph generation and transformation[C]//Thirty-fifth Conference on Neural Information Processing Systems Datasets and Benchmarks Track (Round 2). 2021.二、概述 1、文章提出…

uniapp 持续获取定位(登录状态下才获取)(不采用定时器)(任意页面都可监听定位改变)

基于上次文章做了优化和改良,保证在登录状态下才获取定位信息 uniapp 小程序实时且持续获取定位信息(全局设置一次)(单页面监听定位改变)(不采用定时器)_uniapp小程序定位_前端小胡兔的博客-CSDN博客本篇文章实现了uniapp 微信小程序实时获取定位信息,小程序打开即可持续获取定…

sql查询当前值到最大值中间的数据

方法一 select * from cmp where id >1 and id < max(id)很明显这样做是错的 会报错 invalid use of group function 原因是 max是聚合函数&#xff0c; where条件中不能使用聚合函数 为什么呢 这是一个很有意思的问题&#xff0c;仔细地想一下其实很有道理。我们知道…

Python web实战之Django URL路由详解

概要 技术栈&#xff1a;Python、Django、Web开发、URL路由 Django是一种流行的Web应用程序框架&#xff0c;它采用了与其他主流框架类似的URL路由机制。URL路由是指将传入的URL请求映射到相应的视图函数或处理程序的过程。 什么是URL路由&#xff1f; URL路由是Web开发中非常…

【如何使用cv::erode()函数对图像进行腐蚀操作】

文章目录 `cv::erode()`函数主要用途`cv::erode()`函数的参数卷积核cv::erode()函数主要用途 cv::erode()函数主要用于进行图像的腐蚀操作。这是一种图像处理技术,通常用于消除图像中的噪声、分离两个连接在一起的物体、或者使物体的边界变得更加明显。 腐蚀操作的基本思想是…

go-zero超强工具goctl的常用命令api,rpc,model及其构建的服务解析

goctl api 详情移步&#xff1a; go-zero的路由机制解析 基于go-zero的api服务刨析并对比与gin的区别 goctl rpc goctl支持多种rpc&#xff0c;较为流行的是google开源的grpc&#xff0c;这里主要介绍goctl rpc protoc的代码生成与使用。 protoc是grpc的命令&#xff0c;作用…

用栈实现队列(JS)

用栈实现队列 题目 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;push、pop、peek、empty&#xff09;&#xff1a; 实现 MyQueue 类&#xff1a; void push(int x) 将元素 x 推到队列的末尾int pop() 从队列的开头移除并返回元素int…

ELK日志分析系统概述及部署

ELK 平台是一套完整的日志集中处理解决方案&#xff0c;将 ElasticSearch、Logstash 和 Kibana 三个开源工具配合使用&#xff0c;完成更强大的用户对日志的查询、排序、统计需求。 一、ELK概述 1、组件说明 ①ElasticSearch ElasticSearch是基于Lucene&#xff08;一个全文…

.net core 中间件

先说一下 管道 这个概念&#xff1a; 在ASP.NET Core中&#xff0c;管道&#xff08;Pipeline&#xff09;是一个由多个中间件组成的处理请求和生成响应的机制。请求从第一个中间件开始&#xff0c;经过一系列中间件的处理&#xff0c;然后生成最终的响应。 每个中间件都会处…

Spring Cloud Gateway

一 什么是Spring Cloud Gateway 网关作为流量的入口&#xff0c;常用的功能包括路由转发&#xff0c;权限校验&#xff0c;限流等。 Spring Cloud Gateway 是Spring Cloud官方推出的第二代网关框架&#xff0c;定位于取代 Netflix Zuul。相比 Zuul 来说&#xff0c;Spring Clo…