吃透C++两大默认成员函数:const成员函数、 & 取地址运算符重载


🔥@雾忱星: 个人主页
👀专栏:《C++学习之旅》《Linux学习指南》
💪学习阶段:C/C++、Linux
⏳"人理解迭代,神理解递归。"


文章目录

  • 引言
  • 一、吃透:const成员函数
    • [1.1 基本信息](#1.1 基本信息)
    • [1. 2 重要特性与用法](#1. 2 重要特性与用法)
    • [1.3 const成员函数的意义](#1.3 const成员函数的意义)
  • 二、吃透:取地址运算符重载
    • [2.1 核心语法:必须牢记的规则](#2.1 核心语法:必须牢记的规则)
    • [2.2 核心注意事项(避坑点)](#2.2 核心注意事项(避坑点))
  • 总结

引言

const成员函数与取地址运算符重载是C++类设计的关键知识点,也是高频考点。前者约束成员变量修改、解决const对象调用问题,后者规范自定义类地址获取逻辑,吃透二者可夯实基础、避开语法坑。


一、吃透:const成员函数

1.1 基本信息

定义: const 成员函数是 C++ 类的一种特殊成员函数,它被标记为 const,表示这个函数不会修改所属对象的任何成员变量 (除特殊修饰)。简单来说,const 成员函数是 "只读" 函数,保证调用它时对象的状态不会被改变。

基本语法: 在成员函数的参数列表后、函数体前(包括声明的末尾)添加 const 关键字:

cpp 复制代码
class [类名] 
{
public:
    // 声明 const 成员函数
    [返回值类型] [函数名(参数列表)] const;
};

// 定义 const 成员函数(注意:const 必须和声明保持一致)
[返回值类型] [类名::函数名(参数列表)] const 
{
    // 函数体
}

✍️ 细节:
const 修饰的其实是成员函数参数列表中的 隐含的this指针 Date * const this ------> const Date * const this,达成禁止通过指针解引用修改指针指向的内容(类的成员变量)的目的!

1. 2 重要特性与用法

🔹 (1)不能修改成员变量

cpp 复制代码
#include <iostream>
using namespace std;

class Date
{
public:
	//成员函数
	Date(int year = 1, int month = 1, int day = 1)	//全缺省拷贝构造
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()	const //输出函数,const修饰
	{
		_year++;	//能否自增??
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	//成员变量
	int _year;
	int _month;
	int _day;	
};

void test1()
{
	//创建Date对象
	Date d1(2026, 3, 21);
	d1.Print();
}

int main()
{
	test1();
	return 0;
}

结果很显然,const成员函数无法对成员变量做修改!!

🔹 (2)普通对象可以调用const成员函数、const 对象只能调用 const 成员函数

cpp 复制代码
#include <iostream>
using namespace std;

class Date
{
public:
	//成员函数
	Date(int year = 1, int month = 1, int day = 1)	//全缺省拷贝构造
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print() const //输出函数,const修饰
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	//成员变量
	int _year;
	int _month;
	int _day;	
};

void test1()
{
	//创建Date普通对象
	Date d1(2026, 3, 21);	//相当于权限的缩小,可以调用
	d1.Print();	//2026, 3, 21
	
	// const对象调用const函数
	const Date d2;			//权限的平移,只读,合法
	// 牢记:调用拷贝构造不需要加()
	d2.Print();
}

int main()
{
	test1();
	return 0;
}

1.3 const成员函数的意义

🔹 (1)编译器层面的保护

在成员函数声明后加上 const 关键字,编译器会将该函数内部的 this 指针类型视为 const T* const(指向常量的常量指针)。这意味着:

  • 任何试图修改成员变量的操作都会导致编译错误
  • 只能调用其他 const 成员函数(因为普通成员函数可能修改对象)
  • 这提供了一层编译期的安全保障,防止因疏忽而意外修改对象状态

🔹 (2)支持 const 对象

这是 const 成员函数存在的根本原因:

  • 如果一个对象被定义为 const,那么只能调用它的 const 成员函数
  • 没有 const 成员函数,const 对象将几乎无法使用(只能访问成员变量,但无法调用任何成员函数进行有意义的操作)

这体现了 const 正确性(const correctness)的设计原则

🔹 (3)语义上的承诺

  • 这个函数是一个 "只读" 操作,不会改变对象的逻辑状态
  • 即使通过引用或指针传递 ,调用者也可以放心地传递 const 对象或 const 引用 (权限放大不合法!)
  • 提高了代码的可读性和可维护性,让接口的意图更加明确

核心:

只要成员函数不需要修改成员变量都可以加上const关键字!!


二、吃透:取地址运算符重载

取地址运算符重载分为普通取地址运算符重载const 取地址运算符重载 。在大多数情况下,这两种取地址运算符重载由编译器默认生成的的函数就能够满足我们的需求,除非有一些返回的要求就需要自己手动实现。

2.1 核心语法:必须牢记的规则

🔹 (1)取地址运算符是单目运算符,重载有严格语法限制,错一个细节就会编译报错,核心规则如下:

  • 只能作为类的非静态成员函数重载,禁止全局重载
  • 无任何形式参数,是单目运算符特性决定
  • 必须同时实现普通版本和const成员函数版本,const对象只能调用const版本
  • 返回值一般为对应类型指针this,可以按需求自定义,但不建议返回无效值

🔹 (2)标准重载模板:

cpp 复制代码
class A
{
	//成员函数
public:
	//取地址运算符重载
	//1.普通
	A* operator&()
	{
		return this;
	}

	//2.const
	const A* operator&() const	//const成员函数,只提供给const对象
	{
		return this;
	}
};

🔹 (3) 实战检验:

  • 日常:返回当前类类型对象的的地址
cpp 复制代码
//取地址运算符重载
class A
{
	//成员函数
public:
	//构造函数
	A(int a = 1, int b = 2)
	{
		_a = a;
		_b = b;
	}

	void Print() const
	{
		cout << "_a = " << _a << "_b = " << _b << endl;
	}

	//取地址运算符重载
	//1.普通
	A* operator&()
	{
		return this;
	}

	//2.const
	const A* operator&() const
	{
		return this;
	}

	//成员变量
private:
	int _a = 0;
	int _b = 0;
};

int main()
{
	//普通对象
	A a1;
	A *pa1 = a1.operator&();	//调用方式 1
	A *pa2 = &a1;				//调用方式 2
	cout << pa1 << '\n' << pa2 << endl;

	//const对象
	const A a2;
	const A *pa3 = a2.operator&();
	const A* pa4 = &a2;
	cout << pa3 << '\n' << pa4 << endl;

	return 0;
}
  • 💡 特殊:返回自定义
cpp 复制代码
class A
{
	//成员函数
public:
	//构造函数
	A(int a = 1, int b = 2)
	{
		_a = a;
		_b = b;
	}

	void Print() const
	{
		cout << "_a = " << _a << "_b = " << _b << endl;
	}

	//取地址运算符重载
	//1.普通
	A* operator&()
	{
		//return this;
		return nullptr;
	}

	//2.const
	const A* operator&() const
	{
		//return this;
		return (const A*)0x7ffeefb29c48; //起到混淆作用
	}
	
	//成员变量
private:
	int _a = 0;
	int _b = 0;
};


int main()
{
	//普通对象
	A a1;
	A *pa1 = a1.operator&();
	A *pa2 = &a1;
	cout << pa1 << '\n' << pa2 << endl;

	//const对象
	const A a2;
	const A *pa3 = a2.operator&();
	const A* pa4 = &a2;
	cout << pa3 << '\n' << pa4 << endl;

	return 0;
}

2.2 核心注意事项(避坑点)

🧩取地址运算符重载注意事项

  • 非必要不重载:99%的普通类无需重载,滥用会破坏代码可读性,违背默认语义

  • const版本缺一不可 :只写普通版本,const对象取地址会直接编译失败,必须配套const成员函数

  • 禁止返回无效地址:重载后返回野指针、悬空指针,会导致程序崩溃

  • 不影响内置类型intdouble等基础类型无法重载,仅作用于自定义类对象

  • 默认返回this最稳妥 :无特殊需求,直接返回this指针,保持和默认行为一致,减少异常


总结

html 复制代码
🍓 我是雾忱星⭐!若这篇技术干货帮你打通了学习中的卡点:
👀 【关注】跟我一起深耕技术领域,从基础到进阶,见证每一次成长
❤️ 【点赞】让优质内容被更多人看见,让知识传递更有力量
⭐ 【收藏】把核心知识点、实战技巧存好,需要时直接查、随时用
💬 【评论】分享你的经验或疑问(比如曾踩过的技术坑?),一起交流避坑
🗳️ 【投票】用你的选择助力社区内容方向,告诉大家哪个技术点最该重点拆解
技术之路难免有困惑,但同行的人会让前进更有方向~愿我们都能在自己专注的领域里,一步步靠近心中的技术目标!

结语:

掌握const成员函数需牢记"只读、权限匹配"准则,取地址重载需遵循"非必要不重载、配套const版本"原则。二者能提升代码严谨性,助力理解C++核心设计思想,为进阶学习筑牢根基。

相关推荐
郝学胜-神的一滴1 小时前
中级OpenGL教程 004:为几何体注入法线灵魂
c++·unity·游戏引擎·godot·图形渲染·opengl·unreal
我滴老baby1 小时前
多智能体协作系统设计当AI学会团队合作效率翻十倍
android·开发语言·人工智能
落雪寒窗-1 小时前
Python进阶核心路线(工程向)
开发语言·python
humcomm1 小时前
全栈开发技术栈的最新进展(2026年视角)
开发语言·架构
梵得儿SHI1 小时前
(第三篇)Spring AI 架构设计与优化:容器化与云原生部署,基于 K8s 的 AI 应用全生命周期管理
java·ci/cd·docker·云原生·kubernetes·容器化·spring ai
华万通信king1 小时前
2026 年 GitHub AI 趋势周报:Skills 生态崛起,Agent 框架去中心化
人工智能·去中心化·github
普修罗双战士1 小时前
项目设计-文章系统发布文章完整前后端设计
java·数据库·vue.js·spring boot·git·intellij-idea
鹏程十八少1 小时前
11. 2026金三银四 能答对这 29 道题,你的 Android 插件化就算真正通关了
前端·后端·面试
一切皆是因缘际会2 小时前
大模型幻觉深度解析:成因、落地危害与工程级解决方案
大数据·人工智能·深度学习·安全·ai·架构