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

⚡ CYBER_PROFILE ⚡
/// SYSTEM READY ///


WARNING : DETECTING HIGH ENERGY

🌊 🌉 🌊 心手合一 · 水到渠成

|------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------|
| >>> ACCESS TERMINAL <<< ||
| 🦾 作者主页 | 🔥 C语言核心 |
| 💾 编程百度 | 📡 代码仓库 |


Running Process: 100% | Latency: 0ms


索引与导读

书接上回

上一章我们说到 C++ 中类的前四大默认成员函数,这一章我们把剩下的运算符重载篇给讲完

🔗Lucy的空间骇客裂缝:函数篇


一、类中的 运算符重载 来源

当运算符被⽤于类类型的对象时,C++语⾔允许我们通过运算符重载的形式指定新的含义

C++规定类类型对象使⽤运算符时,必须转换成调⽤对应运算符重载,若没有对应的运算符重载,则会编译报错


二、运算符重载

🔗Lucy的空间骇客裂缝:运算符重载


三、赋值运算符重载

赋值运算符重载是一个特殊的成员函数,用于完成两个已经存在的对象之间的拷贝赋值

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的空间骇客裂缝:深拷贝的使用时机


3)日期类的实现

🔗Lucy的空间骇客裂缝:日期类实现

🚩Date.h (类声明)

cpp 复制代码
#pragma once
#include <iostream>
#include <assert.h>

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 <iostream>
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;
	}
}

💻结尾--- 核心连接协议

警告: 🌠🌠正在接入底层技术矩阵。如果你已成功破解学习中的逻辑断层,请执行以下指令序列以同步数据:🌠🌠


【📡】 建立深度链接: 关注本终端。在赛博丛林中深耕底层架构,从原始代码到进阶协议,同步见证每一次系统升级。

【⚡】 能量过载分发: 执行点赞操作。通过高带宽分发,让优质模组在信息流中高亮显示,赋予知识跨维度的传播力。

【💾】 离线缓存核心: 将本页加入收藏。把这些高频实战逻辑存入你的离线存储器,在遭遇系统崩溃或需要离线检索时,实现瞬时读取。

【💬】 协议加密解密:评论区留下你的散列码。分享你曾遭遇的代码冲突或系统漏洞(那些年踩过的坑),通过交互式编译共同绕过技术陷阱。

【🛰️】 信号频率投票: 通过投票发射你的选择。你的每一次点击都在重新定义矩阵的进化方向,决定下一个被全量拆解的技术节点。



相关推荐
不会C语言的男孩1 天前
C++ Primer Plus 第8章:函数探幽
开发语言·c++
William_wL_1 天前
【C++】模板进阶
c++
MC皮蛋侠客1 天前
Google Test 单元测试指南
c++·单元测试·google test
方也_arkling1 天前
【Java-Day08】static / final / 枚举
java·开发语言
橙淮1 天前
Spring Bean作用域与生命周期全解析
java·spring
艾莉丝努力练剑1 天前
【Linux:文件】Ext系列文件系统进阶
linux·运维·服务器·c++·文件系统·文件io·ext
Chengbei111 天前
一站式源码安全检测工具、云安全 / APP / 小程序源码敏感信息递归多层目录扫描AK、JWT、手机号、身份证等敏感信息
java·开发语言·安全·web安全·网络安全·系统安全·安全架构
llz_1121 天前
web-第一次课后作业
java·开发语言·idea
秋91 天前
Java项目运行5天左右自动宕机:系统性定位与解决方案
java·开发语言·python
小江的记录本1 天前
【JVM虚拟机】垃圾回收GC:垃圾收集器:CMS:核心原理、回收流程、优缺点、废弃原因(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·spring·面试·maven