学习C++(5)运算符重载+赋值运算符重载

1.运算符重载

(1)运算符重载的概念

当运算符被用于类类型的对象时,C++允许通过运算符重载的形式指定特定的含义。C++规定类类型对象使用运算符时,必须转换成调用对应运算符重载,若没有对应的运算符重载,则会编译报错。

运算符重载是具有特殊函数名的函数,函数名由operator和要定义的运算符共同构成。

(2)运算符重载的写法

若运算符重载函数写成全局的,必然会碰到需要访问私有变量的问题,解决方法有:

①将私有成员改为公有(当然这不推荐)

②在对象里提供getxxx函数,代码如下:

cpp 复制代码
#include<iostream>
using namespace std;
class Date
{
public:
    Date(int year = 1, int month = 1, int day = 1)
    {
        _year = year;
        _month = month;
        _day = day;
    }
    void Print()
    {
        cout << _year << "-" << _month << "-" << _day << endl;
    }
    int GetYear() const
    {
        return _year;
    }
    int GetMonth() const
    {
        return _month;
    }
    int GetDay() const
    {
        return _day;
    }
private:
    int _year;
    int _month;
    int _day;
};
bool operator==(const Date& d1,const Date& d2)
{
    return d1.GetYear()==d2.GetYear()
    &&d1.GetMonth()==d2.GetMonth()
    &&d1.GetDay()==d2.GetDay();
}
int main()
{
    Date d1(2026,1,30);
    Date d2(2026,1,31);
    operator==(d1, d2);//显式调用
    d1==d2//隐式调用
    return 0;
}

③友元函数(在后续的内容中介绍,但这种方法同样不推荐)

若运算符重载函数写成成员函数(这是推荐的方法),代码如下:

cpp 复制代码
#include<iostream>
using namespace std;
class Date
{
public:
    Date(int year = 1, int month = 1, int day = 1)
    {
        _year = year;
        _month = month;
        _day = day;
    }
    void Print()
    {
        cout << _year << "-" << _month << "-" << _day << endl;
    }
    bool operator==(const Date& d)
    {
        return _year == d._year
               && _month == d._month
               && _day == d._day;
    }
private:
    int _year;
    int _month;
    int _day;
};

int main()
{
    Date d1(2026,1,30);
    Date d2(2026,1,31);
    d1.operator==(d2);//显式调用
    d1==d2//隐式调用
    return 0;
}
(3)运算符重载的特性

①重载运算符函数的参数个数和该运算符作用的运算对象数量一样多。

②运算符重载以后,其优先级和结合性与对应的内置类型运算符保持一致。

③不能通过连接语法中没有的符号来创建新的操作符,例如operator@。

④**++.* :: sizeof ?: .++**这五个运算符不能重载

⑤重载操作必须至少有一个类类型参数,不能通过运算符重载改变内置类型对象运算符原先的含义

⑥重载++运算符时,有前置++和后置++,C++规定,后置++重载时,增加一个int形参,跟前置++构成函数重载,方便区分,代码如下:

cpp 复制代码
#include<iostream>
using namespace std;
class Date
{
public:
    Date(int year = 1, int month = 1, int day = 1)
    {
        _year = year;
        _month = month;
        _day = day;
    }
    void Print()
    {
        cout << _year << "-" << _month << "-" << _day << endl;
    }
    Date& operator++()//前置++
    {
        //...
        return *this;
    }
    Date operator++(int)//后置++
    {
        Date tmp;
        //...
        return tmp;
    }
private:
    int _year;
    int _month;
    int _day;
};

int main()
{
    Date d1(2026,1,30);
    d1.operator++();//前置++显式调用
    ++d1//前置++隐式调用

    d1.operator++(0);//后置++显式调用
    d1++//后置++隐式调用
    return 0;
}

2.赋值运算符重载

赋值运算符重载是一个默认成员函数,用于完成两个已经存在的对象直接的拷贝赋值。

(1)赋值运算符重载的写法

赋值运算符重载是一个运算符重载,规定必须重载为成员函数。赋值运算重载的参数建议写成 const 当前类类型引用,可以提高效率,返回值也建议写成当前类类型引用,有返回值是为了支持连续赋值场景。代码如下:

cpp 复制代码
#include<iostream>
using namespace std;
class Date
{
public:
    Date(int year = 1, int month = 1, int day = 1)
    {
        _year = year;
        _month = month;
        _day = day;
    }
    void Print()
    {
        cout << _year << "-" << _month << "-" << _day << endl;
    }
    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;
};

int main()
{
    Date d1(2026,1,30);
    Date d2(2026,1,31);
    d1.operator=(d2);//显式调用
    d1=d2//隐式调用
    return 0;
}
(2)赋值运算符重载的特性

①没有显式实现时,编译器会自动生成一个默认赋值运算符重载,默认赋值运算符重载行为跟默认拷贝构造函数类似,对内置类型成员变量会完成值拷贝,对自定义类型成员变量会调用它的赋值重载函数。

②如果一个类显式实现了析构并释放资源,那么它就需要显式写赋值运算符重载,否则就不需要。

相关推荐
吃好睡好便好6 小时前
白发的根源和应对
学习·生活
自然语6 小时前
基于场景、需求、方法匹配和学习评价的垂直移动任务控制系统
学习
旅僧6 小时前
Π0 理论讲解更新中
学习
知南x7 小时前
【DPDK例程学习】(3) timer
学习
「維他檸檬茶」8 小时前
大模型算法学习2026.6.13
学习·算法
代码续发8 小时前
AI Agent的学习记录
学习
ken22329 小时前
文本编辑器默认字体 收集
学习
H__Rick9 小时前
C51学习-DAY6
单片机·嵌入式硬件·学习
YM52e9 小时前
手写模型集合书籍鸿蒙PC ArkTS 对象字面量类型问题约束深度解析
学习·华为·harmonyos·鸿蒙
hhcgchpspk10 小时前
xss漏洞学习笔记
笔记·学习·网络安全·xss