C++运算符重载实战:让类像内置类型一样运算
·
一、上期回顾
吃透 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,重载
+实现两个复数相加 - 重载
<<直接打印复数对象 - 给带指针成员的类实现深拷贝赋值重载
更多推荐

所有评论(0)