C++ 笔记 运算符重载(面象对象)

张开发
2026/4/20 18:11:09 15 分钟阅读

分享文章

C++ 笔记 运算符重载(面象对象)
运算符重载是 C 面向对象编程的重要特性它让自定义类对象可以像普通基本数据类型int、double 等一样使用、-、*、/、、、--等运算符大幅提升代码的可读性和简洁性。本文从核心概念、语法、常用运算符重载实现、注意事项全面讲解帮你快速掌握。一、运算符重载基础1. 什么是运算符重载本质给 C 原有运算符重新定义功能使其能处理自定义类的对象。运算符本质是一种特殊的函数重载就是定义这个函数不创建新运算符仅对现有运算符重新实现不改变运算符的优先级、结合性和操作数个数。2. 语法格式作为类成员函数重载最常用返回值类型 operator 运算符(参数列表) { // 实现逻辑 }作为全局函数重载返回值类型 operator 运算符(参数列表) { // 实现逻辑 }关键字operator 要重载的运算符如operator、operator3. 调用方式两种写法完全等价// 隐式调用简洁推荐 对象1 对象2; // 显式调用本质编译器底层执行 对象1.operator(对象2);二、常用运算符重载实战我们以 ** 坐标类Point** 为例实现最常用的运算符重载包含、-、、!、前置、后置、赋值运算符1. 加号运算符 实现两个坐标对象相加返回新的坐标对象。#include iostream using namespace std; class Point { private: int x, y; public: Point(int x 0, int y 0) : x(x), y(y) {} // 成员函数重载 1个参数右侧运算对象 Point operator(const Point p) { return Point(x p.x, y p.y); } void show() { cout x x , y y endl; } }; int main() { Point p1(1, 2), p2(3, 4); Point p3 p1 p2; // 等价 p1.operator(p2) p3.show(); // 输出x4, y6 return 0; }2. 相等 / 不等运算符 / !判断两个对象的成员变量是否相等// 在Point类中添加 bool operator(const Point p) { return x p.x y p.y; } bool operator!(const Point p) { return !(*this p); // 复用代码 }3. 自增运算符 重点区分前置 / 后置这是面试高频考点前置 和后置 重载语法不同// 1. 前置返回引用效率更高 Point operator() { x; y; return *this; } // 2. 后置int是占位参数区分前置返回临时对象 Point operator(int) { Point temp *this; // 保存旧值 x; y; return temp; // 返回旧值 }4. 赋值运算符 必须掌握编译器会默认生成赋值运算符但类中有指针成员时必须手动重载深拷贝否则会出现和浅拷贝一样的内存崩溃问题。// 赋值运算符重载深拷贝示例 class Student { private: char* name; public: Student(const char* n) { name new char[strlen(n)1]; strcpy(name, n); } // 重载 解决浅拷贝问题 Student operator(const Student s) { // 1. 先释放自身原有内存 if (name ! NULL) { delete[] name; name NULL; } // 2. 深拷贝重新分配内存复制数据 name new char[strlen(s.name)1]; strcpy(name, s.name); return *this; } ~Student() { delete[] name; } };5. 左移运算符 全局函数重载用于直接输出对象必须重载为全局函数友元// 类内声明友元 friend ostream operator(ostream out, const Point p); // 类外实现 ostream operator(ostream out, const Point p) { out x p.x , y p.y; return out; // 支持链式调用cout p1 p2 } // 使用 cout p1 endl;三、成员函数 VS 全局函数重载表格运算符类型重载方式参数个数说明双目运算符 - * / 成员函数1 个左侧对象是 this 指针单目运算符 --成员函数0 个 / 1 个占位前置无参后置 int 占位左移 / 右移全局函数友元2 个不能用成员函数赋值运算符成员函数1 个只能成员重载四、不能重载的运算符C 中有 5 个运算符无法重载牢记即可成员访问运算符.作用域解析符::三目运算符?:长度运算符sizeof类型 id 运算符typeid五、运算符重载三大原则不改变原有语义 就做加法不要实现减法逻辑能成员重载就不全局成员函数可以直接访问私有成员更简洁有指针必重载 赋值运算符必须做深拷贝防止内存崩溃。六、完整示例代码#include iostream using namespace std; class Point { private: int x, y; public: Point(int x0, int y0) : x(x), y(y) {} // Point operator(const Point p) { return Point(xp.x, yp.y); } // bool operator(const Point p) { return xp.x yp.y; } // 前置 Point operator() { x, y; return *this; } // 后置 Point operator(int) { Point temp *this; x, y; return temp; } // 友元声明 friend ostream operator(ostream out, const Point p); }; // 重载 ostream operator(ostream out, const Point p) { out x p.x , y p.y; return out; } int main() { Point p1(1,2), p2(3,4); Point p3 p1 p2; cout p1p2: p3 endl; p3; cout 前置: p3 endl; p3; cout 后置: p3 endl; cout p1p2? (p1p2) endl; return 0; }总结运算符重载是operator运算符的函数让对象支持常规运算成员函数重载最常用 / 必须全局友元重载前置 返回引用效率高后置 用 int 占位区分类有指针成员时必须重载赋值运算符做深拷贝不重载.、::、?:、sizeof、typeid。

更多文章