目录
一、前言
二、什么是成员函数(Member Function)
2.1 正式定义
2.2 为什么需要成员函数(意义)
1)让“数据 + 行为”形成封装
2)自动访问成员变量(不需额外传参)
3)让“第一个参数”隐式传递(this 指针)
三、成员函数的核心:this 指针
3.1 this 是什么
四、const 成员函数:不会修改当前对象
五、运算符重载中的成员函数(核心重点)
5.1 成员函数形式的运算符重载
5.2 参数解读:const Vec2& other
5.3 完整示例:Vec2 向量 + 运算符
六、表格 — 成员函数 vs 普通函数
七、面试常问
7.1 成员函数和普通函数的区别?
7.2 成员函数后面的 const 修饰的是什么?
7.3 为什么 operator+ 通常写成员函数?
八、总结
一、前言
成员函数(member function)是 C++ 类最核心的组成部分,但很多初学者只知道“写在类里的函数就是成员函数”,却没有真正理解:
为什么要有成员函数?
成员函数和普通函数有什么本质区别?
this 指针到底是什么?
成员函数后面的 const 修饰哪里?
运算符重载为什么经常写成员函数?
a + b 为什么能翻译成 a.operator+(b)?
本篇文章一次性全部展开,让你彻底搞懂 C++ 成员函数的底层原理与语法细节。
在之前的学习中,已经详细介绍了运算符重载 以及 构造函数和析构函数的详细内容,链接如下:
一篇搞懂 C++ 重载:函数重载 + 运算符重载,从入门到会用(含 ++、<<、== 实战)-CSDN博客https://blog.csdn.net/m0_58954356/article/details/155323257?sharetype=blogdetail&sharerId=155323257&sharerefer=PC&sharesource=m0_58954356&spm=1011.2480.3001.8118C++ 成员函数运算符重载深度解析-CSDN博客
https://blog.csdn.net/m0_58954356/article/details/155754511?spm=1001.2014.3001.5502
C++ 内存机制详细全讲解:构造函数、析构函数、new/delete、栈 vs 堆 完整指南(小白教程)_结构体构造函数是堆内存还是栈内存-CSDN博客https://blog.csdn.net/m0_58954356/article/details/155098091?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171491c908ae9b99b3e03fdcd0a5d077%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=171491c908ae9b99b3e03fdcd0a5d077&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-155098091-null-null.nonecase&utm_term=%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0&spm=1018.2226.3001.4450
二、什么是成员函数(Member Function)
2.1 正式定义
成员函数是:
定义在类内部、专门用来操作该类对象的函数。
形式:
class ClassName { public: 返回类型 函数名(参数列表) [const]; };它具有普通函数所不具备的特性:
属于类
自动携带隐藏参数
this能访问类的所有成员(包括 private)
支持const 成员函数语义
调用方式直观:对象.函数()
2.2 为什么需要成员函数(意义)
1)让“数据 + 行为”形成封装
Car c; c.startEngine(); c.brake();更符合面向对象语义。
2)自动访问成员变量(不需额外传参)
speed = speed + 10; // 实际是 this->speed += 10;如果用普通函数:
accelerate(&c, 10);语义明显不如成员函数自然。
3)让“第一个参数”隐式传递(this 指针)
你写:
a + b;本质是:
a.operator+(b);再底层一点:
Vec2::operator+(&a, b);成员函数的语法让调用更自然。
三、成员函数的核心:this 指针
3.1 this 是什么
每个成员函数内部,都存在一个隐式参数:
ClassName* this;它指向:
调用这个成员函数的对象本身。
例:
class Vec2 { public: double x, y; void print() { std::cout << x << ", " << y; } };本质等价于:
void print(Vec2* this) { std::cout << this->x << ", " << this->y; }所以:
x等价于this->xy等价于this->y
四、const 成员函数:不会修改当前对象
形式:
返回类型 函数名() const;这个 const 修饰整个函数,而不是返回值。
含义:
承诺不修改成员变量(除非 mutable)
this 指针的类型变成
const ClassName*可在 const 对象上调用
示例:
class Vec2 { public: double x, y; double length() const { return std::sqrt(x * x + y * y); } }; const Vec2 v(3, 4); v.length(); // ✔ 允许,因 length 是 const 成员函数如果不是const成员函数,会编译报错。
五、运算符重载中的成员函数(核心重点)
5.1 成员函数形式的运算符重载
你写:
Vec2 c = a + b;编译器翻译成:
Vec2 c = a.operator+(b);成员函数的定义:
Vec2 Vec2::operator+(const Vec2& other) const;再底层理解:
Vec2::operator+(&a, b);5.2 参数解读:const Vec2& other
含义:
引用传递
&:避免拷贝,提高效率。const:表示不能修改 other:
other.x = 10; // ❌ 编译报错为什么要这样写?
安全、高效、通用(可接受 const、非 const、临时对象)
5.3 完整示例:Vec2 向量 + 运算符
class Vec2 { public: double x, y; Vec2(double x = 0, double y = 0) : x(x), y(y) {} // 成员函数 + const + 引用参数 Vec2 operator+(const Vec2& other) const { return Vec2(x + other.x, y + other.y); } // 只读成员函数 double length() const { return std::sqrt(x * x + y * y); } };调用:
Vec2 a(1, 2); Vec2 b(3, 4); Vec2 c = a + b; // a.operator+(b) double len = c.length();六、表格 — 成员函数 vs 普通函数
| 特性 | 成员函数 | 普通函数 |
|---|---|---|
| 属于类 | ✔ | ✘ |
| 隐式 this | ✔ | ✘ |
| 能否访问 private | ✔ | ✘(除非 friend) |
| 是否支持 const | ✔ | ✘ |
| 调用方式 | 对象.函数() | 函数(对象) |
| 常见用途 | 封装、运算符重载 | 工具函数 |
七、面试常问
7.1 成员函数和普通函数的区别?
成员函数多一个 this 隐式参数
能访问类内部所有成员
支持 const 成员函数
属于类的一部分
7.2 成员函数后面的 const 修饰的是什么?
→ 修饰整个函数,表示该函数不会修改当前对象。
7.3 为什么 operator+ 通常写成员函数?
✔ 左操作数天然绑定到 this
✔ 语义自然 a + b
✔ 能访问 private 成员
✔ const、引用参数用法更直观
八、总结
成员函数 = 属于类的函数 + 隐式 this + 能访问所有成员 + 支持 const 语义,是 C++ 面向对象的核心。