一、上期回顾
吃透 C++ 内存五分区、new/delete与malloc/free区别、内存泄漏、野指针、堆内存规范管理。今天攻克运算符重载,让自定义结构体 / 类像内置类型一样直接做加减、赋值、输出。
二、运算符重载核心概念
1. 什么是运算符重载
对已有运算符重新定义函数逻辑,适配自定义类,不改变:运算符优先级、结合性、操作数个数。
2. 可重载 / 不可重载
可重载:+ - * / = == != < > << >> [] -> &不可重载::: . .* ?:
3. 两种重载形式
- 成员函数重载
- 全局函数重载(友元常用)
三、成员函数重载 + 号(自定义点类相加)
#include <iostream> using namespace std; class Point { private: int x, y; public: Point(int a = 0, int b = 0) : x(a), y(b) {} // 成员函数重载 + Point operator+(const Point& p) { return Point(x + p.x, y + p.y); } void show() { cout << x << " , " << y << endl; } }; int main() { Point p1(1,2); Point p2(3,4); Point p3 = p1 + p2; p3.show(); // 4 , 6 return 0; }四、赋值运算符重载operator=
默认拷贝是浅拷贝,涉及堆内存必须手动重载=实现深拷贝。
class Person { private: int* age; public: Person(int a) { age = new int(a); } // 赋值重载 深拷贝 Person& operator=(const Person& p) { // 防止自赋值 if(this == &p) return *this; // 释放自身旧空间 delete age; // 重新开辟拷贝 age = new int(*p.age); return *this; } ~Person() { delete age; } void print() { cout << *age << endl; } };五、流运算符重载<< >>必须全局友元
cout << 对象不能用成员函数重载,只能全局函数 + 友元:
class Point { private: int x, y; // 声明友元 friend ostream& operator<<(ostream& os, const Point& p); public: Point(int a = 0, int b = 0) : x(a), y(b) {} }; // 重载 << ostream& operator<<(ostream& os, const Point& p) { os << "(" << p.x << "," << p.y << ")"; return os; } int main() { Point p(5,6); cout << p << endl; return 0; }同理>>输入重载写法一致。
六、关系运算符重载 == / !=
bool operator==(const Point& p) { return x == p.x && y == p.y; }七、浅拷贝 vs 深拷贝(面试高频)
浅拷贝
默认编译器生成、逐字节赋值,只拷贝地址,多个对象共享同一块堆内存,析构重复释放崩溃。
深拷贝
重新开辟新堆内存,各自拥有独立空间,互不干扰。触发场景:类中有指针成员、堆内存时,必须:
- 自定义拷贝构造
- 重载赋值运算符
operator=
八、今日核心总结
- 运算符重载不改变优先级、操作数个数
- 算术 / 关系运算符常用成员函数重载
<< >>流运算符只能全局友元重载- 有指针堆成员时,必须重载
=+ 自定义拷贝构造 - 核心目的:让自定义类像内置类型一样运算、赋值、打印
九、课后练习
- 写复数类 Complex,重载
+实现两个复数相加 - 重载
<<直接打印复数对象 - 给带指针成员的类实现深拷贝赋值重载