C++ 类和对象篇(八) const成员函数和取地址运算符重载

目录

一、const成员函数

[1. const成员函数是什么?](#1. const成员函数是什么?)

[2. 为什么有const成员函数?](#2. 为什么有const成员函数?)

[3. 什么时候需要使用const修饰成员函数?](#3. 什么时候需要使用const修饰成员函数?)

二、取地址运算符重载

[1. 为什么需要重载取地址运算符?](#1. 为什么需要重载取地址运算符?)

[2. 默认取地址运算符重载函数](#2. 默认取地址运算符重载函数)

[3. 默认const取地址运算符重载函数](#3. 默认const取地址运算符重载函数)

[4. 什么时候要显示重载取地址运算符?](#4. 什么时候要显示重载取地址运算符?)


一、const成员函数

1. const成员函数是什么?

const修饰的成员函数称为const****成员函数,这个const是用来修饰隐藏的this指针的。

cpp 复制代码
class B{
public:
	int func()const
	{
	}
};
将 const修饰的"成员函数"称之为 const成员函数,const修饰类成员函数,
实际修饰该成员函数隐含的 this指针,表明在该成员函数中不能对类的任何成员进行修改。

2. 为什么有const成员函数?

const成员函数的出现解决了两个问题:

  1. 如何保证无法通过成员函数修改成员变量?
  2. const对象无法调用非const成员函数。

1. const成员函数保证了无法通过成员函数修改成员变量


2. const成员函数能被const对象调用,不会产生权限放大问题。


3. 为什么const对象无法调用非const成员函数?

每个成员函数第一个参数都是隐藏的this指针,对象在调用成员函数时会将对象的地址传给这个this指针,但将const对象传给this指针就会造成权限放大问题。

this 指针本身是 类名* const 类型的,比如Date类的this指针类型是 Date* const,这里的const在*后面,不同于const Date对象取地址后的类型:const Date* 【在*之前修饰,代表该指针指向对象的内容不能被修改(地址里的内容不能改);在*之后修饰,代表该指针指向的对象不能被修改(指向的地址不能改)】,而且const 对象只有读权限,而this指针*前没const修饰有读写权限,所以对象在调用成员函数将对象的地址传给这个this指针时,会造成权限放大问题。

3. 什么时候需要使用const修饰成员函数?

需要修改类中成员变量的成员函数(如专门用来修改成员变量的修改器),就不需要用const修饰。如果一个函数中不需要修改成员变量,建议加const进行修饰,因为const成员函数const对象可以调用,非const对象也可以调用。


请思考下面的几个问题:

  1. const对象可以调用非const成员函数吗?
    答案:不可以,传递this指针时权限会放大
  2. 非const对象可以调用const成员函数吗?
    答案:可以,传递this指针时权限缩小
  3. const成员函数内可以调用其它的非const成员函数吗?
    答案:不可以,传递this指针时权限会放大
  4. 非const成员函数内可以调用其它的const成员函数吗?
    答案:可以,传递this指针时权限缩小

二、取地址运算符重载

1. 为什么需要重载取地址运算符?

在上篇文章C++ 类和对象篇(七) 运算符重载中,分析了重载运算符的原因:为了让自定义类型能使用运算符。重载取地址运算符的目的也是如此:让自定义类型也能使用取地址运算符(&)。

2. 默认取地址运算符重载函数

类中有6个默认成员函数,其中就有默认取地址运算符重载函数,所以即使类中没有定义取地址运算符重载函数,对象依然能使用取地址运算符(&):

3. 默认const取地址运算符重载函数

const取地址运算符重载函数也是默认成员函数,所以即使类中没有定义取地址运算符重载函数,const对象依然能使用取地址运算符(&):

4. 什么时候要显示重载取地址运算符?

一般不需要写,编译器生成的默认的取地址和const取地址运算符重载函数完全够用。特殊情况下,比如不想让别人获取对象的地址,就可以自己实现,返回nullptr:

cpp 复制代码
如果不想让别人获取对象的地址,就可以重载取地址运算符,返回nullptr:
class A
{
public:
	A* operator&()
	{
		return nullptr;
	}
	const A* operator&()const
	{
		return nullptr;
	}
};
int main()
{
	A a;
	const A b;
	cout << &a << endl;
	cout << &b << endl;
	return 0;
}

------------------------END-------------------------

才疏学浅,谬误难免,欢迎各位批评指正。

相关推荐
wuminyu1 小时前
专家视角看Java字节码加载与存储指令机制
java·linux·c语言·jvm·c++
万粉变现经纪人1 小时前
如何解决 pip install llama-cpp-python 报错 未安装 CMake/Ninja 或 CPU 不支持 AVX 问题
开发语言·python·开源·aigc·pip·ai写作·llama
清风明月一壶酒2 小时前
OpenClaw自动处理Word文档全流程
开发语言·c#·word
其实防守也摸鱼2 小时前
CTF密码学综合教学指南--第五章
开发语言·网络·笔记·python·安全·网络安全·密码学
木喃的井盖2 小时前
无锁队列细节
c++·工程
王老师青少年编程2 小时前
csp信奥赛C++高频考点专项训练之字符串 --【字符串基础】:输出亲朋字符串
c++·字符串·csp·高频考点·信奥赛·专项训练·输出亲朋字符串
WBluuue2 小时前
数据结构与算法:莫队(一):普通莫队与带修莫队
c++·算法
小郑加油3 小时前
python学习Day12:pandas安装与实际运用
开发语言·python·学习
AC赳赳老秦3 小时前
投标合规提效:用 OpenClaw 实现标书 / 合同自动审核、关键词校验、格式优化,降低废标风险
开发语言·前端·python·eclipse·emacs·deepseek·openclaw
KuaCpp3 小时前
C++面向对象(速过复习版)
开发语言·c++