本系列 C++ 相关文章 仅为笔者学习笔记记录,用自己的理解记录学习!C++ 学习系列将分为三个阶段:基础篇、STL 篇、高阶数据结构与算法篇,相关重点内容如下:
- 基础篇:类与对象(涉及C++的三大特性等);
- STL 篇:学习使用 C++ 提供的 STL 相关库;
- 高阶数据结构与算法篇: 手动实现自己的 STL 库 及 设计实现高阶数据结构,如 B树、B+树、红黑树等。
学习集:
- C++ 入门到入土!!!学习合集
- Linux 从命令到网络再到内核!学习合集
本期内容:【C++ 基础篇:22】:类的 const 成员变量/属性 与 const 成员函数/方法 以及 类中涉及 const 的常见问题!
目录:
1. const 成员函数的基本认识
2. 代码示例探讨问题:类的 const 对象
- - 2.1 直接表述式分析
- - 2.2 结合代码式分析
3. const 成员函数的写法!
- - 3.1 基本写法框架
- - 3.2 错误代码示例修改并测试结果
4. 类中涉及 const 的常见问题!
5. 相关文章推荐
【 C++学习合集链接 】
1. const 成员函数的基本认识
- 将 const 修饰的“成员函数”称之为 const 成员函数!
- const 修饰类成员函数,实际修饰该成员函数隐含的 this 指针,表明在该成员函数中不能对类的任何成员进行修改。(如何理解请看第二点分析,及第三点的实际使用)
注:此处涉及了之前内容中提及的类中 *this 问题:相关文章点击直达
2. 代码示例探讨问题!
在阅读代码中请记住 const 修饰成员函数的意义:实际修饰该成员函数隐含的 this 指针,表明在该成员函数中不能对类的任何成员进行修改。
提问:如下代码是是否能正常运行通过?【分析讨论看代码后文字内容】
#include<iostream>
using std::cout;
using std::endl;
class Date {
public:
Date(int year = 2000, int month = 1, int day = 1) {
_year = year;
_month = month;
_day = day;
}
void Print() {
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main() {
// 此前学习的基本示例化方式
Date d1(2023, 5, 23);
// 使用 const 修饰实例化对象!
const Date d2(2023, 5, 24);
d1.Print();
d2.Print();
return 0;
}
运行结果:
2.1 直接表述式分析
由图可知:程序报错!如上代码中,在实例化示例中使用了 const 修饰!回顾此前对类的介绍中提及过:类是通过 「*this 指针」 实现对不同实例对象的辨别的! 而我们提及的 「*this 指针」 是作为类中的成员函数的第一个(隐藏)参数!其形式为:typename* const this!
/* 以构造函数为例 */ void Date( Date* const this, int year, int month, int day){]
显然,从报错中我们可知,实际上我们的使用的 d2 对象是具有 const 修饰的!也就是说我们的标识 d2 的 「*this 指针」 也应该使用 const 修饰!但是回顾此前对 「*this 指针」 介绍时提及过,我们不能对这个隐藏默认参数进行显示传递与接收!那我们该怎么解决这个问题呢?
解决方式:根据前文介绍:const 成员函数的作用是?
2.2 结合代码式分析
首先注意到实例化的两个对象!(字面区别就是有无 const 修饰!)
// 使用 引用与指针的权限思路理解 Date d1(2023, 5, 23); // 可读可写 const Date d2(2023, 5, 24); // 只可读
注意到 Print() 函数:注意参数类型!!!
// 函数字面声明的原型如下: void Print() {} // 实际中编译器会翻译作: void Print(Date* const this){} /* 简而言之,就是隐藏了 this 指针! 且 this 指针是被 const 修饰(注意 const 在 * 之后的意义!!!)! */
回顾两个实例化对象本身:
// 字面形式 Date d1(2023, 5, 23); const Date d2(2023, 5, 24); // 编译器翻译的形式: Date d1(&d1, 2023, 5, 23); const Date d2(&d2, 2023, 5, 24); /* 注意: &d1、&d2 是什么类型? */
执行以下语句并获取结果!
/* 执行以下语句: */ cout << typeid(&d1).name() << endl; cout << typeid(&d2).name() << endl; /* 结果: */ class Date * class Date const *
结合上述结果及函数的参数类型可看出问题!
/* &d1:Date * &d2:Date const * 函数参数:Date * 【 const 只是修饰指针的! 】 从权限角度看来,函数接收的是可读可写参数,传递过来的是只读!在函数内使用时就是权限放大(不可行!只能平行或缩小!) 由此:得出问题的关键就是在于参数问题! 由此前知识点可知:类的默认隐含参数是不可以显示接收及传递的!那该如何使 Date * => Date const * 解决方案:const 成员函数【 const 修饰类成员函数,实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。 】 */
3. const 成员函数的写法!
3.1 基本写法框架
基本写法如下:
type function_name() const /* 注意 const 的位置及作用 */
{
}
3.2 错误代码示例修改并测试结果
对 Print() 函数进行修改!
void Print() const /* 注意此处修改! */
{
cout << _year << "-" << _month << "-" << _day << endl;
}
4. 类中涉及 const 的常见问题!
- const 对象可以调用非 const 成员函数吗?
- 非 const 对象可以调用 const 成员函数吗?
- const 成员函数内可以调用其它的非 const 成员函数吗?
- 非 const 成员函数内可以调用其它的 const 成员函数吗?
- 同名函数有无 const 修饰是否构成重载?
提示:实践是检验真理的唯一标准!
5. 相关文章推荐
1. C++ 学习 ::【基础篇:11】:C++ 类的基本使用与非静态 this 指针(两个面试考点):类的空指针问题(this指针可以为空吗?) | this指针存在哪里?