当前位置: 首页 > news >正文

C++学习笔记23:const 成员函数

目录

一、为什么需要 const 成员函数?

二、const 成员函数的写法

三、const 修饰的到底是什么?

四、const 成员函数不能修改成员变量

五、const 对象和普通对象的调用规则

1. const 对象只能调用 const 成员函数

2. 普通对象可以调用 const 成员函数

3. 普通对象也可以调用普通成员函数

六、成员函数之间的调用规则

1. 普通成员函数可以调用 const 成员函数。

2. const 成员函数不能调用普通成员函数

七、在日期类中的应用

八、构造函数和析构函数能不能加 const?

九、const 成员函数和 const 引用参数的关系

十、小结


一、为什么需要 const 成员函数?

在C++中,如果一个对象被 const 修饰,那么这个对象就不能被修改。

例如:

const Date d(2024, 5, 1);

这里 d 是一个 const 对象,表示它的内容不能被修改。

如果我们写一个普通成员函数:

void Print() { cout << _year << "-" << _month << "-" << _day << endl; }

然后让 const 对象调用它:

const Date d(2024, 5, 1); d.Print();

这时可能会编译错误。

原因是:普通成员函数没有承诺不修改对象,而 const 对象不允许被修改。

所以 C++ 提供了const 成员函数


二、const 成员函数的写法

const 成员函数就是在成员函数参数列表后面加上 const。

例如:

void Print() const { cout << _year << "-" << _month << "-" << _day << endl; }

完成示例:

#include <iostream> using namespace std; class Date { public: Date(int year = 2024, int month = 1, int day = 1) { _year = year; _month = month; _day = day; } void Print() const { cout << _year << "-" << _month << "-" << _day << endl; } private: int _year; int _month; int _day; }; int main() { const Date d(2024, 5, 1); d.Print(); return 0; }

运行结果:

2024-5-1

加上 const 后,const 对象就可以正常调用 Print() 了。


三、const 修饰的到底是什么?

成员函数后面的 const,本质上修饰的是隐藏的 this 指针指向的对象。

普通成员函数中,this 指针可以理解为:

Date* const this

也就是:

this 指针本身不能改变指向的 但 this 指向的对象可以被修改

而 const 成员函数中,this 指针可以理解为:

const Date* const this

也就是说:

this 指针本身不能改变; this 指向的对象也不能被修改。

所以在 const 函数中,不能修改成员变量。


四、const 成员函数不能修改成员变量

例如:

void Print() const { _year = 2025; // 错误 cout << _year << "-" << _month << "-" << _day << endl; }

这段代码会报错。

原因是 Print() 被声明成了 const 成员函数,函数内部不能修改点给钱对象的成员变量。

所以 const 成员函数适用于:

只读取对象数据,不修改对象状态的函数

比如:

void Print() const; bool operator==(const Date& d) const; bool operator<(const Date& d) const; int GetMonthDay(int year, int month) const;

五、const 对象和普通对象的调用规则

成员函数调用时,有一套权限规则。

1. const 对象只能调用 const 成员函数

const Date d(2024, 5, 1); d.Print();

如果 Print() 是普通成员函数,就可能报错。

应该写成:

void Print() const { cout << _year << "-" << _month << "-" << _day << endl; }

2. 普通对象可以调用 const 成员函数

Date d(2024, 5, 1); d.Print();

如果 Print() 是 const 成员函数,普通对象也可以调用。

因为普通对象权限更大,调用只读函数属于权限缩小,是安全的。


3. 普通对象也可以调用普通成员函数

Date d(2024, 5, 1); d.Print();

普通对象本来就可以修改,所以可以调用普通成员函数。


简单总结:

对象类型普通成员函数const成员函数
普通对象可以调用可以调用
const对象不能调用可以调用

六、成员函数之间的调用规则

成员函数内部也会涉及到 const 权限问题。

1. 普通成员函数可以调用 const 成员函数。

class Date { public: void Func1() { Func2(); } void Func2() const { cout << "Func2" << endl; } };

这是可以的。

因为普通成员函数中的 this 是 Date*,调用 const 成员函数时,可以转换换成 const Date*,属于权限缩小。


2. const 成员函数不能调用普通成员函数

class Date { public: void Func1 const () { Func2(); // 错误 } void Func2() { cout << "Func2" << endl; } };

这是错误的。

因为 const 成员函数中的 this 是 const Date*,如果调用普通成员函数,就相当于把 const Date* 转成 Date*,属于权限放大,不允许。


七、在日期类中的应用

之前写日期类比较运算符时,可写成这样:

bool operator==(const Date& d) { return _year == d._year && _month == d._month && _day == d._day; }

这个函数知识比较日期,不会修改当前对象。

所以更规范的写法应该是:

bool operator==(const Date& d) const { return _year == d._year && _month == d._month && _day == d._day; }

同理,下面这些比较函数也应该加 const:

bool operator>(const Date& d) const; bool operator<(const Date& d) const; bool operator>=(const Date& d) const; bool operator<=(const Date& d) const; bool operator!=(const Date& d) const;

这样 const Date 对象也可以正常调用这些函数。

哪些成员函数应该加 const?判断标准很简单:

只要这个成员函数不修改成员变量,就应该加 const。

不能加 const 的函数一般是会修改对象的,比如:

Date& operator+=(int day); Date& operator-=(int day); Date& operator++(); Date& operator--();

八、构造函数和析构函数能不能加 const?

构造函数和析构函数不能写成 const 成员函数?

例如下面这种写法是错误的:

Date() const { } ~Date() const { }

原因是构造函数和析

构函数本身负责对象的初始化和清理,不属于普通成员函数调用的场景。

所以:

构造函数不能加 const 析构函数不能加 const

九、const 成员函数和 const 引用参数的关系

实际写代码时,函数经常会此写成:

void Func() (const Date& d) { d.Print(); }

这里 d 是 const Date&,也就是一个只读对象。

如果 Print() 没有加 const:

void Print() { }

那么:

d.Print();

就会报错。

所以如果一个对象可以 const 引用形式传参,那么它调用的成员函数也应该是 const 成员函数。

这也是为什么在日期类中,Print()、比较运算符等不修改对象的函数 ,都应该加上const。


十、小结

本篇主要学习了C++中的 const 成员函数。

需要记住:

  1. const 成员函数是成员函数参数列表后面加 const;
  2. const 成员函数的本质是限制 this指针指向的对象不能修改;
  3. 普通对象可以调用普通成员函数和const 成员函数;
  4. const 对象只能调用 const 成员函数;
  5. const 成员函数内部不能修改成员变量;
  6. 普通成员函数可以调用 const 成员函数;
  7. const 成员函数不能调用普通成员函数;
  8. 不修改成员变量的函数都建议加 const;
  9. 构造函数和析构函数都不能加 const;
  10. 日期类中的比较函数、打印函数通常都应该写成 const 成员函数。

const 成员函数是写规范C++类代码时非常重要的知识点。理解它之后,就能很好的处理 const 对象、const 引用参数以及成员函数之间的调用权限问题。

http://www.cnnetsun.cn/news/2518467.html

相关文章:

  • 3分钟让Figma说中文:设计师必备的汉化插件完全指南
  • 无SDK环境下如何使用curl命令调试Taotoken大模型接口
  • 3PEAK思瑞浦 TP6002-FR DFN2X2-8 运算放大器
  • 软件测试的缺陷管理:这4个工具+5个流程,让你的缺陷管理更高效
  • 让 AI Agent 更可靠:Harness Engineering 与多 Agent 系统工程实践
  • 2026年图片去水印软件哪个好用?盘点当前值得收藏的去水印工具
  • 千问 LeetCode 2565. 最少得分子序列 Java实现
  • 千问 LeetCode 2569. 更新数组后处理求和查询 Java实现
  • 观察taotoken在多模型间自动路由的响应速度与成功率
  • 基于Python + LLM的AI导演系统设计与实现
  • 6款论文降AIGC工具亲测:AI痕迹彻底消失,这款便宜又好用
  • AI写作辅助软件的合规秘籍:如何界定“合理使用”与学术不端?
  • awesome-canvas进阶技巧:Canvas与WebGL结合开发高性能图形应用
  • easy-vibe 核心功能解析:解锁 Vibe Coding 的终极技巧
  • CANN/cannbot-skills Git差异统计
  • CANN/asc-devkit浮点转hif8 API
  • 如何通过3个步骤快速掌握Java反编译界面定制:终极指南
  • PHP版本管理的终极解决方案:3分钟掌握phpenv多版本切换技巧
  • B站直播神器:神奇弹幕全方位操作指南
  • H5P交互式视频制作终极指南:快速创建引人入胜的互动学习内容
  • 中小团队如何利用 Taotoken 统一管理多模型 API 密钥与成本
  • 一天一个开源项目(第108篇):Andrej Karpathy Skills - 用一个 CLAUDE.md 文件修复 LLM 编码的四个顽疾
  • 免费图片去水印工具有哪些?2026 在线图片去水印软件推荐指南
  • 3步掌握Internet Archive Downloader:突破数字图书馆限制的终极浏览器扩展工具
  • 终极B站直播助手:3分钟搭建智能直播间,效率提升300%
  • CANN/pypto:MatmulAllReduce与RMSNorm融合算子
  • BuckyClient性能优化:sample与aggregationInterval参数调优实践
  • ElevenLabs支持广西话吗?2024最新实测结果曝光:仅2个API参数决定能否合成地道“梧州腔”
  • 英伟达VR200机柜PCB价值量同比+233%:AI硬件主线如何被引爆?
  • 从“水本原论”的时空错位看西方哲学叙事的建构与AI时代的数据霸权