【C++入门】Cyber骇客构造器的核心六元组 —— 【类的默认成员函数】明明没写构造函数也能跑?保姆级带你掌握六大类的默认成员函数(下:运算符重载)

⚡ CYBER_PROFILE ⚡
/// SYSTEM READY ///


WARNING \]: DETECTING HIGH ENERGY **🌊 🌉 🌊 心手合一 · 水到渠成** ![分隔符](https://i-blog.csdnimg.cn/direct/60a3de2294e9439abad47378e657b337.gif) |------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------| | **\>\>\> ACCESS TERMINAL \<\<\<** || | [**\[ 🦾 作者主页 \]**](https://blog.csdn.net/fengtinghuqu520?spm=1000.2115.3001.5343) | [**\[ 🔥 C语言核心 \]**](https://blog.csdn.net/fengtinghuqu520/category_12955956.html) | | [**\[ 💾 编程百度 \]**](https://blog.csdn.net/fengtinghuqu520/category_13083835.html) | [**\[ 📡 代码仓库 \]**](https://blog.csdn.net/fengtinghuqu520/article/details/147275999?spm=1001.2014.3001.5502) | --------------------------------------- Running Process: 100% \| Latency: 0ms *** ** * ** *** #### 索引与导读 * [书接上回](#书接上回) * [一、类中的 运算符重载 来源](#一、类中的 运算符重载 来源) * [二、运算符重载](#二、运算符重载) * [三、赋值运算符重载](#三、赋值运算符重载) * * [1)编译器自动生成的默认重载](#1)编译器自动生成的默认重载) * [2)深拷贝的使用时机](#2)深拷贝的使用时机) * [3)日期类的实现](#3)日期类的实现) * * [🚩Date.h (类声明)](#🚩Date.h (类声明)) * [🚩Date.cpp (成员函数实现)](#🚩Date.cpp (成员函数实现)) * [🚩Main.cpp (测试入口)](#🚩Main.cpp (测试入口)) * [四、取地址运算符重载](#四、取地址运算符重载) * * [取地址运算符的形式](#取地址运算符的形式) * [💻结尾--- 核心连接协议](#💻结尾— 核心连接协议) ## 书接上回 上一章我们说到 `C++` 中类的前四大默认成员函数,这一章我们把剩下的运算符重载篇给讲完 > 🔗[Lucy的空间骇客裂缝:函数篇](https://blog.csdn.net/fengtinghuqu520/article/details/157220158?spm=1001.2014.3001.5501) *** ** * ** *** ## 一、类中的 运算符重载 来源 当运算符被⽤于类类型的对象时,`C++`语⾔允许我们通过运算符重载的形式指定新的含义 `C++`规定类类型对象使⽤运算符时,必须转换成调⽤对应运算符重载,若没有对应的运算符重载,则会编译报错 *** ** * ** *** ## 二、运算符重载 > [🔗Lucy的空间骇客裂缝:运算符重载](https://blog.csdn.net/fengtinghuqu520/article/details/157391516?spm=1011.2415.3001.10575&sharefrom=mp_manage_link) *** ** * ** *** ## 三、赋值运算符重载 赋值运算符重载是一个特殊的成员函数,用于完成两个已经存在的对象之间的拷贝赋值 ```cpp class Date { public: Date(int year = 2024, int month = 1, int day = 1) : _year(year), _month(month), _day(day) {} // 1. 必须是成员函数 // 2. 参数采用 const 引用:避免拷贝构造,提高效率 // 3. 返回值采用 引用(Date&):支持连续赋值 (d1 = d2 = d3) 且效率高 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; }; ``` **╔═█▓▒░ CODE CORE 🔥** **┌─────────────┐ │ 代码关键点 │ └─────────────┘** 1. 必须是成员函数 2. 参数采用 `const` 引用:避免拷贝构造,提高效率 3. 返回值采用 引用(`Date&`):支持连续赋值 (`d1 = d2 = d3`) 且效率高 *** ** * ** *** ### 1)编译器自动生成的默认重载 在`C++`中,如果你没有为类显式定义`operator=`,**编译器会为你秘密地生成一个默认赋值运算符重载** *** ** * ** *** * **`内置类型`** : * **非指针:** 进行"`浅拷贝`" * **指针:** 仅仅复制地址,不指向复制的内容 ```cpp class Simple { public: int num; int* ptr; }; ``` **逻辑效果:** `a.num = b.num; ` *直接数值复制* `a.ptr = b.ptr; ` *仅复制地址,a和b指向同一内存* *** ** * ** *** * **`类对象成员`** :递归调用 `operator=` 如果成员本身是一个类对象,编译器会"委托"给该成员自己的赋值运算符 ```cpp class Member { public: Member& operator=(const Member& obj) { /* 自定义逻辑 */ return *this; } }; class Wrapper { public: Member m; }; ``` **逻辑效果:** `wrapperA.m = wrapperB.m;` 自动调用 Member 类的 operator= *** ** * ** *** * **`基类`** :自动调用基类的赋值运算符 在继承体系中,派生类的默认赋值会自动处理基类部分的赋值 ```cpp class Base { public: int b_val; }; class Derived : public Base { public: int d_val; }; ``` **逻辑效果:** `derA.Base::operator=(derB);` 先处理基类成员 b_val `derA.d_val = derB.d_val;` 再处理派生类成员 d_val *** ** * ** *** ### 2)深拷贝的使用时机 > [🔗Lucy的空间骇客裂缝:深拷贝的使用时机](https://blog.csdn.net/fengtinghuqu520/article/details/157693655?spm=1011.2415.3001.10575&sharefrom=mp_manage_link) *** ** * ** *** ### 3)日期类的实现 > [🔗Lucy的空间骇客裂缝:日期类实现](https://gitee.com/maple-lake-district/coding/commit/4bec43b39254142299b9636d7603a78b15f50ceb) #### 🚩Date.h (类声明) ```cpp #pragma once #include #include class Date { // 友元函数:流操作符重载 friend std::ostream& operator<<(std::ostream& out, const Date& d); friend std::istream& operator>>(std::istream& in, Date& d); public: Date(int year = 1900, int month = 1, int day = 1); void Print() const; bool CheckDate() const; // 获取某月天数:内联提高效率,static避免重复创建数组 inline int GetMonthDay(int year, int month) const { assert(month > 0 && month < 13); static int monthDayArray[13] = { -1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))) { return 29; } return monthDayArray[month]; } // 比较运算符 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; // 算术运算符 Date& operator+= (int day); Date operator+ (int day) const; Date& operator-= (int day); Date operator- (int day) const; // 前置与后置 ++/-- Date& operator++(); // ++d Date operator++(int); // d++ Date& operator--(); // --d Date operator--(int); // d-- // 日期 - 日期 int operator-(const Date& d) const; private: int _year; int _month; int _day; }; ``` *** ** * ** *** #### 🚩Date.cpp (成员函数实现) ```cpp #include "Date.h" using namespace std; Date::Date(int year, int month, int day) { _year = year; _month = month; _day = day; if (!CheckDate()) { cout << "警告:日期初始化非法 -> "; Print(); } } bool Date::CheckDate() const { if (_month < 1 || _month > 12 || _day < 1 || _day > GetMonthDay(_year, _month)) { return false; } return true; } void Date::Print() const { cout << _year << "-" << _month << "-" << _day << endl; } // --- 比较运算符复用 --- bool Date::operator==(const Date& d) const { return _year == d._year && _month == d._month && _day == d._day; } bool Date::operator<(const Date& d) const { if (_year < d._year) return true; if (_year == d._year && _month < d._month) return true; if (_year == d._year && _month == d._month && _day < d._day) return true; return false; } 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, _month)) { _day -= GetMonthDay(_year, _month); ++_month; if (_month == 13) { ++_year; _month = 1; } } 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; 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++() { return *this += 1; } Date Date::operator++(int) { Date tmp(*this); *this += 1; return tmp; } Date& Date::operator--() { return *this -= 1; } Date Date::operator--(int) { Date tmp(*this); *this -= 1; return tmp; } // 日期减日期:算出间隔天数 int Date::operator-(const Date& d) const { Date max = *this, 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; } // --- 流重载 --- ostream& operator<<(ostream& out, const Date& d) { out << d._year << "年" << d._month << "月" << d._day << "日"; return out; } istream& operator>>(istream& in, Date& d) { in >> d._year >> d._month >> d._day; if (!d.CheckDate()) { cout << "输入日期非法,请检查!" << endl; } return in; } ``` *** ** * ** *** #### 🚩Main.cpp (测试入口) ```cpp #include "Date.h" #include using namespace std; int main() { Date d1(2024, 2, 1); cout << "初始日期 d1: " << d1 << endl; // 测试加法 Date d2 = d1 + 30; cout << "d1 + 30天: " << d2 << endl; // 测试日期相减 Date d3(2025, 2, 1); cout << "2025-2-1 与 2024-2-1 相差: " << (d3 - d1) << " 天" << endl; // 测试输入 Date d4; cout << "请输入一个日期 (年 月 日): "; cin >> d4; cout << "你输入的日期是: " << d4 << endl; return 0; } ``` *** ** * ** *** *** ** * ** *** ## 四、取地址运算符重载 ### 取地址运算符的形式 * **普通对象** ```cpp class MyClass { public: // 针对普通对象的取地址重载 MyClass* operator&() { return this; // 默认行为 } } ``` * **常对象** ```cpp class MyClass { public: const MyClass* operator&() const { return this; } } ``` *** ** * ** *** ## 💻结尾--- 核心连接协议 **警告:** 🌠🌠正在接入底层技术矩阵。如果你已成功破解学习中的逻辑断层,请执行以下指令序列以同步数据:🌠🌠 *** ** * ** *** **【📡】 建立深度链接:** **关注**本终端。在赛博丛林中深耕底层架构,从原始代码到进阶协议,同步见证每一次系统升级。 **【⚡】 能量过载分发:** 执行**点赞**操作。通过高带宽分发,让优质模组在信息流中高亮显示,赋予知识跨维度的传播力。 **【💾】 离线缓存核心:** 将本页加入**收藏**。把这些高频实战逻辑存入你的离线存储器,在遭遇系统崩溃或需要离线检索时,实现瞬时读取。 **【💬】 协议加密解密:** 在**评论区**留下你的散列码。分享你曾遭遇的代码冲突或系统漏洞(那些年踩过的坑),通过交互式编译共同绕过技术陷阱。 **【🛰️】 信号频率投票:** 通过**投票**发射你的选择。你的每一次点击都在重新定义矩阵的进化方向,决定下一个被全量拆解的技术节点。 *** ** * ** *** ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/57b03915c54b43a7a03fa92dbbfe57c3.gif) ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/0905dc972de8414bb602715de3f866ee.gif)

相关推荐
寻寻觅觅☆8 小时前
东华OJ-基础题-106-大整数相加(C++)
开发语言·c++·算法
fpcc8 小时前
并行编程实战——CUDA编程的Parallel Task类型
c++·cuda
青云计划9 小时前
知光项目知文发布模块
java·后端·spring·mybatis
赶路人儿9 小时前
Jsoniter(java版本)使用介绍
java·开发语言
ceclar12310 小时前
C++使用format
开发语言·c++·算法
探路者继续奋斗10 小时前
IDD意图驱动开发之意图规格说明书
java·规格说明书·开发规范·意图驱动开发·idd
lanhuazui1010 小时前
C++ 中什么时候用::(作用域解析运算符)
c++
charlee4410 小时前
从零实现一个生产级 RAG 语义搜索系统:C++ + ONNX + FAISS 实战
c++·faiss·onnx·rag·语义搜索
老约家的可汗10 小时前
初识C++
开发语言·c++
消失的旧时光-194311 小时前
第十九课:为什么要引入消息队列?——异步系统设计思想
java·开发语言