[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.hqwc.cn/news/55784.html

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

相关文章

UI自动化测试之Jenkins配置

背景: 团队下半年的目标之一是实现自动化测试,这里要吐槽一下,之前开发的测试平台了,最初的目的是用来做接口自动化测试和性能测试,但由于各种原因,接口自动化测试那部分功能整个废弃掉了,其中…

Spring 事务管理

目录 1. 事务管理 1.1. Spring框架的事务支持模型的优势 1.1.1. 全局事务 1.1.2. 本地事务 1.1.3. Spring框架的一致化编程模型 1.2. 了解Spring框架的事务抽象(Transaction Abstraction) 1.2.1. Hibernate 事务设置 1.3. 用事务同步资源 1.3.1…

Agent:OpenAI的下一步,亚马逊云科技站在第5层

什么是Agent?在大模型语境下,可以理解成能自主理解、规划、执行复杂任务的系统。Agent也将成为新的起点,成为各行各业构建新一代AI应用必不可少的组成部分。 对此,初创公司Seednapse AI创始人提出构建AI应用的五层基石理论&#…

Python数据分析实战-dataframe指定多列去重(附源码和实现效果)

实现功能 Python数据分析实战-利用df.drop_duplicates(subset[,])对dataframe指定多列去重 实现代码 import pandas as pddata{state:[1,1,2,2,1,2,2],pop:[a,b,c,d,b,c,d]} framepd.DataFrame(data)frameframe.drop_duplicates(subset[pop,state]) print(frame) 实现效果 本…

rv1109/1126 rknn 模型部署过程

rv1109/1126是瑞芯微出的嵌入式AI芯片,带有npu, 可以用于嵌入式人工智能应用。算法工程师训练出的算法要部署到芯片上,需要经过模型转换和量化,下面记录一下整个过程。 量化环境 模型量化需要安装rk的工具包: rockchip-linux/rk…

每日一题——两数之和

题目 给出一个整型数组 numbers 和一个目标值 target,请在数组中找出两个加起来等于目标值的数的下标,返回的下标按升序排列。 (注:返回的数组下标从1开始算起,保证target一定可以由数组里面2个数字相加得到&#xff0…

Ceph入门到精通-远程开发Windows下使用SSH密钥实现免密登陆Linux服务器

工具: win10、WinSCP 服务器生成ssh密钥: 打开终端,使账号密码登录,输入命令 ssh-keygen -t rsa Winscp下载 Downloading WinSCP-6.1.1-Setup.exe :: WinSCP window 生成密钥 打开powershell ssh-keygen -t rsa 注意路径 …

ArcGIS Pro简介下载安装地址

ArcGIS Pro简介 ArcGIS Pro是一款功能强大的地理信息系统(GIS)软件,由Esri开发。它为用户提供了一种直观、灵活且高效的方式来处理、分析和可视化地理数据。ArcGIS Pro具有现代化的用户界面和工作流程,使用户能够更好地利用地理信…

【DDPM扩散模型】DDPM扩散模型公式推导

🔥 🔥 【参考】轻松学习扩散模型(diffusion model),被巨怪踩过的脑袋也能懂——原理详解pytorch代码详解(附全部代码) 纸上得来终觉浅,绝知此事要躬行。

Python实现GA遗传算法优化Catboost回归模型(CatBoostRegressor算法)项目实战

说明:这是一个机器学习实战项目(附带数据代码文档视频讲解),如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 遗传算法(Genetic Algorithm,GA)最早是由美国的 John holland于20世…

IDEA项目实践——创建Java项目以及创建Maven项目案例、使用数据库连接池创建项目简介

系列文章目录 IDEA上面书写wordcount的Scala文件具体操作 IDEA创建项目的操作步骤以及在虚拟机里面创建Scala的项目简单介绍 目录 系列文章目录 前言 一 准备工作 1.1 安装Maven 1.1.1 Maven安装配置步骤 1.1.2 解压相关的软件包 1.1.3 Maven 配置环境变量 1.1.4 配…

leaflet-uniapp 缩放地图的同时 显示当前缩放层级

记录实现过程: 需求为移动端用户在使用地图时,缩放地图的同时,可以获知地图此时缩放的级别。 效果图如下:此时缩放地图级别为13 map.on() 有对应的诸多行为 查看官网即可,这里根据需要为--zoomstart zoom zoomend 代…