文章目录
一、赋值运算符重载
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取地址操作符,除非有充分理由,因为这可能违反用户预期
如果重载了取地址操作符,确保行为合理且文档化