当前位置: 首页 > news >正文

《C++》面向对象编程--类(下)

文章目录

  • 一、赋值运算符重载
    • 1.1定义
    • 1.2基本规则
    • 1.3为什么需要运算符重载?
    • 1.4示例:
  • 二、前置++和后置++区别
    • 2.1前置++的实现与特点
    • 2.2后置++的实现与特点
    • 2.3核心区别
  • 三、const
  • 四、取地址及const取地址操作符重载
    • 4.1定义
    • 4.2语法
    • 4.3注意事项

一、赋值运算符重载

1.1定义

运算符重载是C++的一项特性,允许我们为自定义类型(类或结构体)重新定义运算符的行为(如+, -, =, ==等),使其像内置类型一样直观操作。如果用户没有显式实现时,编译器会生成一个默认赋值运算符重载,以值的方式逐字节拷贝。

1.2基本规则

1. 函数命名

运算符重载函数的名称必须是 operator 后接运算符符号。

返回值类型 operator运算符(参数列表)

示例:

ClassName& operator=(const ClassName& other) {if (this != &other) {  // 关键点1:自赋值检查// 释放旧资源 + 深拷贝新资源}return *this;  // 关键点2:返回引用支持链式赋值
}

2. 关键限制
❌ 不能创建新运算符(如 operator@ 是非法的)。
❌ 不能修改内置类型的运算符含义(例如 int 的 + 必须保持加法语义)。
❌ 以下运算符不可重载:
.* :: sizeof ?: .
3. 参数规则

  • 如果重载为成员函数,第一个操作数是隐式的 this,参数比操作数少1。
    例如 a + b 会调用 a.operator+(b)。

  • 如果重载为全局函数,参数数量必须与操作数一致。
    例如 operator+(a, b)。

1.3为什么需要运算符重载?

  • 提升代码可读性:date1 < date2 比 date1.isEarlierThan(date2) 更直观。

  • 保持一致性:让自定义类型像内置类型一样工作。

  • 支持标准库算法:如 std::sort 依赖 < 运算符。

1.4示例:

h文件:
#pragma once
#pragma once
#include<iostream>
using namespace std;class Date
{
public:Date(int year = 1, int month = 1, int day = 1);void Print(){cout << _year << "-" << _month << "-" << _day << endl;}bool operator<(const Date& x);bool operator==(const Date& x);bool operator<=(const Date& x);bool operator>(const Date& x);bool operator>=(const Date& x);bool operator!=(const Date& x);int GetMonthDay(int year, int month);//+xx天的情况Date& operator+=(int day);Date operator+(int day);Date& operator++();Date operator++(int);
private:int _year;int _month;int _day;
};
cpp文件
#include "20250722A.h"Date::Date(int year, int month, int day)
{_year = year;_month = month;_day = day;
}bool Date::operator<(const Date& x)
{if (_year < x._year){return true;}else if (_year == x._year && _month < x._month){return true;}else if (_year == x._year && _month == x._month && _day < x._day){return true;}return false;
}bool Date::operator==(const Date& x)
{return _year == x._year&& _month == x._month&& _day == x._day;
}bool Date::operator<=(const Date& x)
{return *this < x || *this == x;
}bool Date::operator>(const Date& x)
{return !(*this <= x);
}bool Date::operator>=(const Date& x)
{return !(*this < x);
}bool Date::operator!=(const Date& x)
{return !(*this == x);
}int Date::GetMonthDay(int year, int month)
{static int daysArr[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))//先判断month是否等于2可以提高效率{return 29;}else{return daysArr[month];}
}Date& Date::operator+=(int 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)
{Date tmp(*this);tmp += day;return tmp;}
int main()
{Date d1(2025, 7, 24);d1 = d1 + 100;d1.Print();return 0;
}

二、前置++和后置++区别

2.1前置++的实现与特点

Date& Date::operator++() {*this += 1;      // 调用已重载的+=return *this;    // 返回当前对象的引用
}

使用示例:

Date d(2023, 1, 1);
++d;  // 等价于 d.operator++()

2.2后置++的实现与特点

Date Date::operator++(int) {Date tmp = *this;  // 保存旧值*this += 1;        // 修改当前对象return tmp;        // 返回旧值副本
}

使用示例:

Date d1(2023, 1, 1);
Date d2 = d1++;  // d2获得旧值,d1自增

2.3核心区别

在这里插入图片描述

// 前置++(推荐)
for (int i = 0; i < n; ++i)  // 无临时对象生成// 后置++
for (int i = 0; i < n; i++)  // 每次循环构造临时int

故我们更推荐使用前置++。

三、const

const 是 C++ 中的关键字,用于定义"常量"或"不可修改"的变量、函数参数、成员函数等。它的核心作用是增强程序的安全性和可读性,帮助编译器在编译阶段发现潜在的错误。

  • const对象只能调用const成员函数
  • const成员函数对任何对象都是安全的
  • const成员函数内不可以调用其它的非const成员函数
  • 非const成员函数内可以调用其它的const成员函数

四、取地址及const取地址操作符重载

4.1定义

在 C++ 中,取地址操作符 & 可以被重载,包括普通版本和 const 版本。这种重载允许你控制当用户获取类对象地址时的行为。

4.2语法

class MyClass {
public:// 普通取地址操作符重载MyClass* operator&() {return this; // 通常返回 this,但可以自定义}// const 取地址操作符重载const MyClass* operator&() const {return this; // 通常返回 this,但可以自定义}
};

4.3注意事项

  • 通常不建议重载取地址以及const取地址操作符,除非有充分理由,因为这可能违反用户预期

  • 如果重载了取地址操作符,确保行为合理且文档化

http://www.dtcms.com/a/296825.html

相关文章:

  • IPv6网络优化
  • ANSYS Fluent 管内流动仿真
  • 如何恢复mysql,避免被研发删库跑路
  • Python(09)正则表达式
  • 无人机云台跟踪目标实现
  • springboot项目建立sse接口
  • tokenID和位置嵌入有关系吗,qwen 模型使用时候仅仅有tokenid 映射为向量,位置编码在哪里
  • C++的虚基类?
  • 黑马头条项目详解
  • cmake应用:集成gtest进行单元测试
  • MUX同步器
  • 人工智能概念:常用的模型压缩技术(剪枝、量化、知识蒸馏)
  • 一篇文章了解HashMap和ConcurrentHashMap的扩容机制
  • ESP32入门实战:PC远程控制LED灯完整指南
  • pandas库的数据导入导出,缺失值,重复值处理和数据筛选,matplotlib库 简单图绘制
  • AD一张原理图分成多张原理图
  • iview Select的Option边框显示不全(DatePicker也会出现此类问题)
  • rust-参考与借用
  • 爬虫逆向--Day12--DrissionPage案例分析【小某书评价数据某东评价数据】
  • MySQL零基础教程增删改查实战
  • java后端
  • mujoco playground
  • DBA常用数据库查询语句
  • DevOps 完整实现指南:从理论到实践
  • 论文阅读:《Many-Objective Evolutionary Algorithms: A Survey. 》多目标优化问题的优化目标评估的相关内容介绍
  • Android LiveData 全面解析:原理、使用与最佳实践
  • Rust生态中的LLM实践全解析
  • 【C# 找最大值、最小值和平均值及大于个数和值】2022-9-23
  • 项目质量如何提升?
  • 教育培训系统源码如何赋能企业培训学习?功能设计与私有化部署实战