C++类成员函数中const的用法

2023-11-16

C++类中,const的用法个人总结主要有以下几种:

1. 用来修饰成员变量,比如const int var;

2. 用来修饰形参,主要针对引用,比如const type&

3. 用来修饰返回值,返回常量引用;

4.放在成员函数的形参列表的“)”之后,大括号“}”之前;

#include <iostream>
#include <string>
using namespace std;
class Person
{
	public:
		//构造函数 
		Person() = default;
		Person(const string& name, const string& id, unsigned age) : 
		m_name(name), m_age(age), m_id(id) {  }
		//公有的接口
		const string& name() const { return m_name; } 
		const string& id() const {return m_id; }
		unsigned age() const { return m_age; }
		void set_name(const string& name) { m_name = name; }
	private:
		//C++支持类内初始值 
		string m_name = "";
		const string m_id = ""; //常量数据成员
		unsigned m_age = 0;
};

比如定义了上面的Person类,对4种用法分别进行总结:

1. const用来修饰成员变量

用const修饰的成员变量,必须在构造函数的初始化列表中对const修饰的成员进行初始化,比如Person类,在初始化列表中对m_id成员进行了初始化,如果在构造函数体内,不叫初始化,那叫赋值,m_id已经使用了类内初始值初始化了,再对它进行赋值的话,编译报错!

Person(const string& name, const string& id, unsigned age) : 
m_name(name), m_age(age), m_id(id) {  } //正确,在初始化列表对const成员m_id进行初始化

Person(const string& name, const string& id, unsigned age) : m_name(name), m_age(age)
{
    //错误!不能在构造函数体内对const成员赋值
    m_id = id; //这是赋值,不是初始化,m_id已经初始化了,对已经初始化了的const对象赋值,编译报错
}

2. const修饰的形参

const修饰的形参主要针对引用或指针,比如对于类中的成员函数set_name(const string& name)

void set_name(const string& name) { m_name = name; }
//将形参声明为const,是为了使得函数的调用更有弹性,使得使用常量或者非常量都可以调用

int main()
{
    Person p; //调用默认构造函数实例化一个Person的对象p
    const string name1("Megatron"); //const string对象name
    string name2("Galvatron"); //普通的string对象
    p.set_name(name1); //正确!常量引用绑定到常量对象上,如果形参不使用const修饰,无法调用
    p.set_name(name2); //正确,常量引用可以绑定到非常量对象上
}

3. 放在成员函数的形参列表的“)”之后,大括号“}”之前

个人理解:这种情况下const修饰的是this指针所指向的对象*this,就是调用成员函数的对象本身!这里的const就是为了限制成员函数无法对this指向的对象进行修改,此时*this对象是只读的。

(1)编译器也提供检查,一旦检查到成员函数对this指向的对象进行了修改,就报错!

(2)如果在小括号“)”和大括号“{”之间没有使用const,且函数内部没有对*this进行修改,有的情况下会编译出错,比如:

const string& name() 
{
    //小括号和大括号之间没有const
    //函数体内没有没有对this对象修改
    return m_name; 
} 
Person p1("megatron", "xxx-xx-xx-001", 1000);
p1.name() //可以,编译通过!

const Person p2("Galvatron", "xxx-xx-xx-001", 1000);
p2.name() //编译报错!

4. 返回常量引用

如果在小括号“)”和大括号"{"之间加了const,且函数返回类型为引用,则必须返回const引用,返回普通引用编译报错!比如:

string& name() const { return m_name; } 
//右边的const是用来修饰*this的,说明不可以对*this进行修改
//如果左边不加const,只是返回普通的引用,由于引用可以作为左值,可以对其进行赋值,比如
Person p("megatron", "xxx-xx-xx-001", 1000);
p.name() = "Galvatron"; //这样就相当于修改了*this,而右边的const限制了不能对*this进行更改

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++类成员函数中const的用法 的相关文章

  • 线程独占数据:如何存储和访问?

    NET 中是否有可能将对象实例绑定到线程的当前执行上下文 这样在代码的任何部分我都可以做类似的事情CurrentThread MyObjectData DoOperation 并确保我访问特定于线程的数据 谢谢 你可以看一下线程静态属性 h
  • 错误:“运行所选代码生成器时出错:包恢复失败”

    我正在尝试将控制器添加到 ASP NET Core 项目中的解决方案中 当我尝试这样做时 我收到此错误 我收到相同的消息 为控制器添加最小依赖项和完整依赖项 我也有这个问题 使用实体框架添加控制器 gt 带有操作的 API 控制器 将给出
  • 提取单花括号内的值

    我想要一个收藏 value 一个字符串使用正则表达式 例如 lorem ipsum field1 lorem ipsum field2 lorem ipsum field1 lorem ipsum field2 field3 我会得到 fi
  • C 中的 '\0' 和 printf()

    在 C 入门课程中 我了解到在存储字符串时存储空字符 0在它的最后 但是如果我想打印一个字符串怎么办 printf hello 虽然我发现它并没有结束 0通过以下声明 printf d printf hello Output 5 但这似乎不
  • C 链表销毁函数

    我正在尝试学习 C 和很多人一样 我对指针有点困惑 无论如何 我创建了一个递归函数来销毁我的链表 但是正如我调试的那样 当我从函数返回时 列表的头部不应该为空 所以我猜这是对指针的一些基本误解 这是函数 void destroy struc
  • 为什么 ObservableCollection 有两个集合构造函数?

    The 可观察集合 T https msdn microsoft com en us library ms668604类有两个构造函数 可以在其中传递项目集合 一个构造函数接受一个IEnumerable T 另一个List T 鉴于List
  • 使用 LINQ 展平嵌套字典

    所以我有一本形式的字典Dictionary
  • 有没有办法找到dll公开的所有函数

    我一直在寻找一种方法来获取映射到 dll 中函数名称的所有字符串 我的意思是您可以调用 GetProcAddress 的所有字符串 如果你对 dll 进行十六进制转储 符号 字符串 就在那里 但我认为必须有一个系统调用来获取这些名称 如果您
  • 用 OpenCL C 编写快速线性系统求解器

    我正在编写一个 OpenCL 内核 它将涉及求解线性系统 目前我的内核太慢了 提高线性系统部分的性能似乎是一个不错的起点 我还应该注意 我并没有尝试使我的线性求解器并行 我正在研究的问题在宏观层面上已经是令人尴尬的并行 以下是我编写的 C
  • 为什么我收到编译错误“使用已删除的函数 'std::unique_ptr ...”

    我收到一条巨大的编译错误消息 c mingw include c 6 1 0 bits predefined ops h 123 18 error use of deleted function std unique ptr lt Tp D
  • 将 std::pair const 转换为 std::pair const 安全吗?

    理论上或实践上 安全吗reinterpret cast a std pair
  • 是否自初始化 'A a = a;'允许吗?

    此代码在运行时在复制构造函数中失败 但编译器 MSVS2008 没有发出警告 您能解释一下 最好引用标准 这段代码是否非法或什么 我理解 A a a 永远不应该写在第一位 但我正在寻找理论背景 class A public A p new
  • 使用 FromBase64Transform 解码 base64 文件流

    The example https msdn microsoft com en us library system security cryptography frombase64transform 28v vs 110 29 aspx从M
  • 将旧的 Unity 代码升级到 Unity 5

    在触发按钮上播放动画的代码似乎不起作用 我在 Youtube 上看到了一个视频 内容很简单animation Play 它可以在该视频上运行 但我无法让它在我的计算机上运行 我做错了什么还是团结改变了它 请帮助我在网上找不到解决方案 所有
  • 当分配返回 0 时,具有空异常规范的运算符 new 调用构造函数

    我有以下声明 void operator new size t s PersistentMemory m throw return m gt allocatePersistentMemory s 我正在测试启动时的内存耗尽 这会导致m gt
  • C中使用JNI从对象获取对象

    public class Student private People people private Result result private int amount 这是 Java 中类的示例 在C中 我试图获取 学生 中的 人 但失败了
  • NSubstitute - 测试特定的 linq 表达式

    我在当前正在开发的 MVC 3 应用程序中使用存储库模式 我的存储库界面如下所示 public interface IRepository
  • 如何使用 .NET 捕获我的桌面视频?

    我想知道是否有任何方法可以使用 NET 捕获我的桌面的视频 截屏视频 我并不是在寻找截屏软件 而只是在寻找一种可以让我自己生成桌面视频的技术 我想过拍摄多个屏幕截图 但我不确定如何以编程方式生成带有图像序列的视频 有人有主意吗 Thanks
  • DbContext.SaveChangesAsync 异常处理

    当搭建新的脚手架时ApiController通过 Visual Studio 2013 中的异步操作和实体框架支持 某些方法可以包装DbContext SaveChangesAsync https msdn microsoft com en
  • 从其对象获取结构体字段的名称和类型

    例如 我有一个类似这样的结构 struct Test int i float f char ch 10 我有一个该结构的对象 例如 Test obj 现在 我想以编程方式获取字段名称和类型obj 是否可以 顺便说一句 这是 C 你正在要求C

随机推荐

  • 在 Ubuntu 操作中安装Code::Blocks

    在 Ubuntu 操作 中安装Code Blocks 步骤如下 安装步骤 1 先把编译环境 C库 C 库和Boost库装好 如下 sudoapt get install build essential 有可能安装 build essenti
  • R语言常用包介绍

    r与python差异比较大的一个地方就是 python的机器学习算法集中程度比较高 比如sklearn 就集成了很多的算法 而R语言更多时候需要一个包一个包去了解 比较费时费力 对于python转过来的朋友非常不友好 抽空整理了工作中常用的
  • spark创建maven工程创建scala目录并编译

    背景 我创建spark的maven工程的时候 在java目录同级还创建了一个scala目录 这就得考虑编译相关的事了 解决 1 创建source folder 如下图所示 直接创建就好了 2 编译带来的问题 编译的时候发现一个问题 就是在s
  • WSL安装软件报错/sbin/ldconfig.real: /usr/lib/wsl/lib/libcuda.so.1 is not a symbolic link

    原因 usr lib wsl lib 目录下都是文件而不是链接 且该目录只读 需要在其他目录操作 解决 cd usr lib wsl sudo mkdir lib2 sudo ln s lib lib2 更改wsl配置文件 sudo vim
  • VisualStudio怎么一键注释多行以及一键取消多行注释

    一键注释多行代码 Ctrl k 然后 Ctrl c 一键取消多行注释 Ctrl k 然后 Ctrl u
  • 云主机8088端口被挖矿情况以及解决办法

    1 用top命令查询一下有没有CPU占用很高的 hadoop 10 9 15 140 top top 18 59 17 up 2 05 1 user load average 0 36 0 38 0 68 Tasks 97 total 1
  • Unity视频播放之Video Player的简单使用

    使用Unity自带的VideoPlayer来播放视频 一 准备视频 Unity3D常用视频格式 mov mpg mpeg mp4 avi asf 如果都不识别 试试转换成ogv格式 转换完成之后 将视频素材文件拖入Unity Assets文
  • Nginx中的正则匹配表达式操作符“~”和“~*“的含义

    操作符表示区分大小写的匹配 操作符表示不区分大小写的匹配 更多Nginx中正则表达式操作符的知识 请参考下面这个链接 https www cnblogs com bethal p 5514557 html
  • 二进制方式快速部署BSC主网v1.1.2

    文章目录 一 下载bsc主网快照数据 二 下载BSC二进制文件 三 下载主网配置文件及创世区块文件 四 二进制启动BSC主网 五 查询是否同步完成 BSC快照官方 https docs binance org smart chain dev
  • 任意进制的转换(C,C++)itoa函数,strtol函数,bitset函数,oct函数,dec函数,hex函数

    十进制转换为 2 10 进制代码方法 include
  • 单片机实现物体检测(人脸识别等)

    总述 边缘计算很有前景 对于低要求的识别任务完全可以下放到嵌入式设备运行 本文实现的应用基于TF lite Macro框架 实现 训练模型 基于YoloV3修改网络文件进行训练自己的模型 识别单个物体 模型文件机见下文连接 下载Darkne
  • 安装之openjdk

    1 先检查是否安装 dpkg list grep i jdk 2 移除openjdk包 命令 sudo apt get purge openjdk 3 卸载 OpenJDK 相关包 命令 sudo apt get purge icedtea
  • Windows下使用海康相机SDK获取图像并在Qt显示

    点击上方蓝字可直接关注 方便下次阅读 如果对你有帮助 可以点个在看 让它可以帮助到更多同志 一 一些基础信息 MVS 版本 V3 1 0 SDK 版本 V3 2 0 3 1 库与头文件位置 安装完MVS软件后 会有相机SDK的一些资料 如下
  • Sphinx——自动生成Python文档

    Sphinx是一个可自动生成python项目api的工具 使用起来也比较简单 只需要在项目上进行简单的配置 即可生成项目的api文档 简介 Sphinx是Python文档生成器 它基于reStructuredText标记语言 可自动根据项目
  • Vue.js常用的语法(一)

    在一个html文件中 我们直接可以通过script标签引入Vue js 然后就可以在页面里写Vue js代码了 我们通过new Vue 构建了一个Vue的实例 html文件 div p a p div app js var app new
  • 三十二.Python学习笔记.7

    文件和数据格式化 一 文件的使用 1 文件的理解 文件是存储在辅助存储器上的数据序列 文件是数据存储的一种形式 文件展现形态 文本文件和二进制文件 文本文件VS二进制文件 文本文件和二进制文件只是文件的展示方式 本质上 所有文件都是二进制形
  • Openlayer 5 使用坐标点查询最近的图层feature

    Openlayer 5 使用坐标点查询最近的图层feature vector getClosestFeatureToCoordinate coordinates 返回指定图层距离该坐标最近的faeture 官方API getClosestF
  • 音乐生成 - 使用LSTM和Transformer模型进行MIDI音乐生成

    欢迎来到这篇博客 在这篇文章中 我们将讨论如何使用LSTM和Transformer模型生成音乐 特别是MIDI音乐 在这个过程中 我们将使用Python编程语言以及一些常见的库 让我们开始吧 1 简介 深度学习已经在许多领域取得了显著的成功
  • 【经验总结】tcp_tw_recycle参数引发的故障

    tcp tw recycle参数引发的故障 By Eric 故障描述 2010年9月7日 新上线的手机游戏论坛有部分地区用户反应登陆游戏时出现不能登陆或登陆超时等情况 观察用户同时在线数量开始下降情况 排错过程 一 初步检查是否有变更导致的
  • C++类成员函数中const的用法

    C 类中 const的用法个人总结主要有以下几种 1 用来修饰成员变量 比如const int var 2 用来修饰形参 主要针对引用 比如const type 3 用来修饰返回值 返回常量引用 4 放在成员函数的形参列表的 之后 大括号