5.1 运算符重载基本概念1.运算符重载允许用户为类类型的对象赋予运算符新的含义使自定义类型也能像内置类型一样使用、-、等运算符。2.使用运算符时本质上是在调用对应的重载函数。若没有对应的重载函数则编译报错。3.由关键字operator和指定的运算符共同构成与其他函数一样包含返回值类型、参数列表和函数体。// 以 Date 类为例重载 运算符 class Date { public: Date(int year 1, int month 1, int day 1) : _year(year), _month(month), _day(day) {} bool operator(const Date d) const { return _year d._year _month d._month _day d._day; } private: int _year; int _month; int _day; };参数与调用规则1.重载函数的参数个数与运算符的操作数个数一致一元运算符一个参数二元运算符两个参数。2.当运算符重载为成员函数时左侧对象通过隐式的this指针传递因此参数列表比操作数少一个。例如二元运算符重载为成员函数时只需显式写出一个参数。特性重载后的运算符其优先级和结合性与对应的内置类型运算符保持一致不会因为重载而改变。重要限制与注意事项1.不能通过连接语法中没有的符号来创建新的操作符例如operator是非法的。2..*、::、sizeof、?:、.这五个运算符不能被重载是选择题的常考点。3.重载运算符必须至少有一个参数是类类型不能改变内置类型对象的含义。例如int operator(int x, int y)是非法的。4.重载运算符应具有实际意义。例如Date类重载-计算日期差是有意义的而重载则没有明确语义。5.重载后置时需要额外增加一个无用的int形参用于与前置区分。6.必须重载为全局函数且第一个形参为ostream/istream对象第二个形参为自定义类型对象。要是重载为成员函数第一个参数默认传给 this 指针所以就会变成 对象在前cin/cout 在后出现倒反天罡的形式所以说只能重载为全局函数不需要 this 指针直接传参将第一个形参来接收 cin/cout。// 前置 与后置 的重载 class Date { public: // 前置 返回引用减少拷贝 Date operator() { _day 1; return *this; } // 后置 增加一个无用的 int 形参用于区分 // 这里的int只是用于区分并无其他用处传不传参都可 Date operator(int) { Date tmp(*this); //使用拷贝构造等价于 Date tmp *this; _day 1; return tmp; } }; // 与 必须重载为全局函数 // 这里要求将 istream/ostream 作为第一个参数是因为 输入输出是 cin/cout在前直接传参 std::ostream operator(std::ostream out, const Date d) { out d._year - d._month - d._day; return out; }5.2 赋值运算符重载基本概念1.赋值运算符重载是一个默认成员函数用于完成两个已存在对象之间的拷贝赋值。2.需要严格区分拷贝构造与赋值运算符重载。拷贝构造用于对象初始化创建新对象而赋值运算符重载用于已存在对象之间的赋值。Date d1(2024, 1, 1); Date d2(d1); // 拷贝构造d2 是正在初始化的新对象 Date d3; d3 d1; // 赋值运算符重载d3 已存在进行赋值核心特点1.赋值运算符重载规定必须重载为成员函数不能写成全局函数。适用赋值重载时默认会将第一个参数传给 this 指针类外不支持所以将赋值重载写在类外面会报错。有依赖 this 指针实现的函数就实现为成员函数反之实现为全局函数。2.建议写成const当前类类型引用const T避免传值传参产生拷贝。3.有返回值且建议写成当前类类型引用T目的是支持连续赋值例如a b c;。4.若未显式实现编译器会自动生成默认赋值运算符重载。默认行为是逐字节拷贝浅拷贝对自定义类型成员会调用其自身的赋值重载。class Date { public: Date operator(const Date d) { if (this ! d) { // 避免自赋值 _year d._year; _month d._month; _day d._day; } return *this; // 返回引用支持连续赋值 } private: int _year; int _month; int _day; };实现场景与技巧1.若类成员全是内置类型且无资源管理如Date类编译器生成的默认赋值即可满足需求。2.若类涉及资源管理如Stack类中有指针指向堆内存必须实现深拷贝对资源也进行拷贝否则会出现两个对象指向同一块内存的问题。3.若类内部成员是自定义类型如MyQueue中有Stack成员编译器生成的默认赋值会调用成员变量的赋值重载无需额外实现。4.如果一个类显式实现了析构函数说明释放了资源那么它也需要显式实现赋值运算符重载通常还需要显式实现拷贝构造。// 涉及资源管理时必须实现深拷贝 class Stack { public: Stack(int capacity 4) : _a(new int[capacity]) , _top(0) , _capacity(capacity) {} ~Stack() { delete[] _a; _a nullptr; } Stack(const Stack st) : _a(new int[st._capacity]) , _top(st._top) , _capacity(st._capacity) { memcpy(_a, st._a, sizeof(int) * _top); } Stack operator(const Stack st) { if (this ! st) { int* tmp new int[st._capacity]; // 先申请新空间保证异常安全 memcpy(tmp, st._a, sizeof(int) * st._top); delete[] _a; // 释放旧空间 _a tmp; _top st._top; _capacity st._capacity; } return *this; } private: int* _a; int _top; int _capacity; };小结对比项拷贝构造赋值运算符重载作用时机对象初始化时两个已存在对象之间赋值是否可重载为全局可以必须是成员函数返回值建议无特殊要求返回T支持连续赋值默认行为浅拷贝浅拷贝资源管理类需显式实现深拷贝需显式实现深拷贝5.3日期类实现#pragma once #includeiostream #includeassert.h class Date { public: Date(int year 1, int month 1, int day 1); void Print() const; //频繁调用所以在类里面实现默认inline函数 int GetMonthDay(int year, int month) { assert(month 0 month 13); int Day[] { 0,31,28,31,30,31,30,31,31,30,31,30,31 }; if (month 2 ((year % 400 0) || ((year % 4 0) (year % 100 ! 0)))) return 29; return Day[month]; } bool CheckDate(); bool operator(const Date d) const; bool operator(const Date d) const; bool operator(const Date d) const; bool operator(const Date d) const; bool operator(const Date d) const; bool operator!(const Date d) const; // d1 天数 Date operator(int day); Date operator(int day) const; // d1 - 天数 Date operator-(int day); Date operator-(int day) const; // d1 - d2 int operator-(const Date d) const; // d1 - d1.operator() Date operator();//前置 Date operator(int);//后置 Date operator--(); Date operator--(int); int operator-(const Date d); private: int _year; int _month; int _day; };#includeDate.h using namespace std; bool Date::CheckDate() { if (_month 0 || _month 12 || _day1 || _day GetMonthDay(_year, _month)) return false; else return true; } Date::Date(int year,int month,int day) { if (!CheckDate()) cout 日期非法 endl; year _year; month _month; day _day; } void Date::Print() const { cout _year - _month - _day endl; } bool Date::operator(const Date d) const { if (_year d._year) { return true; } else if(_year d._year) { if (_month d._month) return true; else return _day d._day; } return false; } bool Date::operator(const Date d) const { return _year d._year _month d._month _day d._day; } bool Date::operator(const Date d) const { return *this d || *this d; } bool Date::operator(const Date d) const { return !(*this d); } bool Date::operator(const Date d) const { return !(*this d); } bool Date::operator!(const Date d) const { return !(*this d); } //日期 天数 Date Date::operator(int day) { if (_day 0) { return *this - -day; } _day day; while(_day GetMonthDay(_year, _day)) { _day - GetMonthDay(_year, _day); _month; if (_month 13) { _month 1; _year; } } return *this; } Date Date::operator(int day) const { Date tmp *this;//保证自己不被修改同时返回修改之后的值 tmp _day; return tmp; } Date Date::operator-(int day) { if (_day 0) { return *this (-day); } _day - day; while (_day 0) { --_month;//先更新_month,防止出现用 _month 0 去取天数 if (_month 0) { _month 12; _year--; } _day - GetMonthDay(_year, _month); } return *this; } Date Date::operator-(int day) const { Date tmp *this; tmp - day; return tmp; } Date Date::operator() { *this 1; return *this; } Date Date::operator(int) { Date tmp *this; tmp 1; return tmp; } Date Date::operator--() { *this - 1; return *this; } Date Date::operator--(int) { Date tmp *this; tmp - 1; return tmp; } int Date::operator-(const Date d) { Date max *this; Date min d; int flag 1; if (*this d) { max d; min *this; flag -1; } int n 0; while (min ! max) { min; n; } return n * flag; }5.4 const 成员函数1.将const修饰的成员函数称之为const成员函数const修饰成员函数放到成员函数参数列表的后⾯。2.const实际修饰该成员函数隐含的this指针表明在该成员函数中不能对类的任何成员进⾏修改。const 修饰Date类的Print成员函数Print隐含的this指针由 Date* const this 变为 constDate* const this 表示对于指针本身以及指向的内容均不能进行修改。
企业数字化 ERP 产品动态
相关推荐
【面试题】测试面试题2026-01 1. 接手全新业务,如何开展完整测试
核心思路是先摸底、再规划、后执行、终沉淀,避免一上来就埋头写用例、测功能。
业务摸底与风险评估(1-3天)
梳理核心业务链路:输出业务全景图、核心角色、上下游依赖、关键数据流转路… · 2026/11/5 23:22:03
通过服务器中转的git push方法 公司的机器无法访问github,正好有一个阿里云的服务器,用阿里云服务器搭建一个git仓库中转,并且公司禁止ssh连接阿里云,所以这里采用的方法比较麻烦。这里先需要在阿里云上建立一个裸仓库,之后为裸仓库配置remote之后他… · 2026/11/5 23:22:03
Audio学习2(麦克风和喇叭) 想了想,还是看看这两基础哥们。 1 麦克风
1.1 总览
大概有以下这些。
类型换能原理输出信号灵敏度SNR体积成本典型应用MEMS 数字麦(PDM)硅微振膜电容 片内 ΣΔ 调制PDM 1bit 串行中等60~70dB极小(34mm 级)低TWS 耳… · 2026/11/3 22:03:23
EasyU优启通PE维护盘实战指南:制作、启动与核心操作全解析 1. 为什么一个PE维护盘值得单独拿出来聊装系统、修引导、救数据、清病毒,这些活儿但凡干过几次的人都知道,真正决定效率的往往不是你手速多快,而是手边那套PE环境靠不靠谱。EasyU(圈内习惯叫优启通)就是在这个场景下被… · 2026/11/5 16:49:35
Rust原来很简单二:所有权系统 Part 2 核心篇 —— 所有权系统
本篇覆盖 第 6 ~ 10 章:所有权、借用与引用、生命周期、字符串与切片、内存模型。 ⚠️ 这是全书最重要的一篇。 把它吃透,Rust 从此“很简单”;跳过它,你会处处碰壁。请慢下来,动手敲每一段代码。 第 6 章 所有权:Rust 的第一性原理
6… · 2026/11/5 16:26:08
基于Hadoop+Spark的民宿智能推荐系统设计与实现 1. 项目概述:大数据时代的民宿智能推荐这个毕业设计项目融合了当前大数据领域最主流的技术栈,构建了一个完整的民宿推荐系统解决方案。作为一名长期从事大数据系统开发的工程师,我认为这个选题非常贴合实际应用场景——随着旅游业的复苏和共享… · 2026/11/5 14:59:25
ADS122U04IPWR+STM32F427ZI工业级温度测量信号链设计 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 14:10:41
UART接口24位ADC搭配RS485,解决远距离温度监控难题 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 14:10:41
UART接口24位ADC搭配PIC18F46K22的RTD与热电偶测温实践 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 14:10:41
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:27:59
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:28:03
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:28:07
多智能体协作系统架构设计与实践优化 1. 多智能体协作系统的时代背景2017年Transformer架构的诞生彻底改变了人工智能的发展轨迹。当行业还沉浸在单一大模型带来的性能突破时,Anthropic的研究团队已经将目光投向了更前沿的领域——如何让多个智能体通过协作产生超越单体能力的系统智能。这就像交响乐团中… · 2026/11/5 0:00:39
大模型系统性入门实战指南:从原理到部署微调的全链路路线 提到大模型的系统性入门,我先说个结论:这事真不难,难的是资料太散、路线太多,今天这个框架明天那个工具,新人很容易在“收藏夹吃灰”和“教程看到一半放弃”之间反复横跳。市面上关于大模型的内容少说有几十万篇&#… · 2026/11/5 0:00:39
鸿蒙文件系统沙箱机制解析与开发实践 1. 鸿蒙文件系统沙箱机制深度解析作为一名从Android转向鸿蒙开发的工程师,我深刻体会到文件系统访问是迁移过程中最先遇到的"拦路虎"。在Android上运行良好的文件读写代码,在鸿蒙真机环境却频频出现文件写入后神秘消失或直接抛出权限拒绝错误的… · 2026/11/5 0:00:39
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:27:59
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:28:03
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:28:07