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

【C++】运算符重载

运算符重载

C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名以及参数列表。其返回值类型和参数列表与普通的函数类型。

函数名字为:关键字operator后面接需要重载的运算符号

函数原型:返回值类型 operator操作符(参数列表)

注意:

  • 不能通过其他符号来创建新的操作符:比如operator@
  • 重载操作符必须有一个类类型参数
  • 用于内置类型的操作符其含义不能改变,例如:内置的整形+,不能改变其含义
  • 作为类成员函数重载时,其形参看起来必操作数目少1,因为成员函数的第一个参数为隐藏的this
  • .* :: sizeof ?: .注意以上5个运算符不能重载
// 全局的operator==
class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}//private:int _year;int _month;int _day;
};
// 这里会发现运算符重载成全局的就需要成员变量是公有的,那么问题来了,封装性如何保证?
// 这里其实可以用我们后面学习的友元解决,或者干脆重载成成员函数。
bool operator==(const Date& d1, const Date& d2)
{return d1._year == d2._year&& d1._month == d2._month&& d1._day == d2._day;
}
void Test()
{Date d1(2018, 9, 26);Date d2(2018, 9, 27);cout << (d1 == d2) << endl;
}
class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}// bool operator==(Date* this, const Date& d2)// 这里需要注意的是,左操作数是this,指向调用函数的对象bool operator==(const Date& d2){return _year == d2._year&& _month == d2._month&& _day == d2._day;}
private:int _year;int _month;int _day;
};

赋值运算符重载

  1. 赋值运算符重载格式
    • 参数类型const T&,传递引用可以提高传参效率
    • 返回值类型T&,返回引用可以提高返回的效率,有返回值是为了支持连续赋值
    • 检测是否自己给自己赋值
    • 返回*this:要符合连续赋值的含义
class Date {
public:Date(int year, int month, int day) {_year = year;_month = month;_day = day;}Date(const Date& d) {_year = d._year;_month = d._month;_day = d._day;}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;
};
  1. 赋值运算符只能重载成类的成员函数不能重载成全局函数
class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}int _year;int _month;int _day;
};
// 赋值运算符重载成全局函数,注意重载成全局函数时没有this指针了,需要给两个参数
Date& operator=(Date& left, const Date& right)
{if (&left != &right){left._year = right._year;left._month = right._month;left._day = right._day;}return left;
}
// 编译失败:
// error C2801: “operator =”必须是非静态成员

原因:赋值运算符如果不显式实现,编译器会生成一个默认的。此时如果在类外自己实现一个全局赋值运算符重载,就和编译器在类中生成的默认赋值运算符重载冲突了,所以赋值运算符重载只能是类的成员
在这里插入图片描述
3. 用户没有显式实现的时候,编译器会生成一个默认赋值运算符重载,以值的方式逐字节拷贝注意:内置成员类型变量是直接赋值的,而自定义类型成员变量需要调用对应类的赋值运算符重载完成赋值

class Time
{
public:Time(){_hour = 1;_minute = 1;_second = 1;}Time& operator=(const Time& t){if (this != &t){_hour = t._hour;_minute = t._minute;_second = t._second;}return *this;}
private:int _hour;int _minute;int _second;
};
class Date
{
private:// 基本类型(内置类型)int _year = 1970;int _month = 1;int _day = 1;// 自定义类型Time _t;
};
int main()
{Date d1;Date d2;d1 = d2;return 0;
}

既然编译器生成默认的赋值运算符重载函数已经可以完成字节序的值拷贝了,还需要自己实现嘛?当然简单的类是不需要的。还是来看看下面这个例子:
在这里插入图片描述

前置++和后置++重载

class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}// 前置++:返回+1之后的结果// 注意:this指向的对象函数结束后不会销毁,故以引用方式返回提高效率Date& operator++(){_day += 1;return *this;}// 后置++:// 前置++和后置++都是一元运算符,为了让前置++与后置++形成能正确重载// C++规定:后置++重载时多增加一个int类型的参数,但调用函数时该参数不用传递,编译器//自动传递// 注意:后置++是先使用后+1,因此需要返回+1之前的旧值,故需在实现时需要先将this保存//一份,然后给this + 1//       而temp是临时对象,因此只能以值的方式返回,不能返回引用Date operator++(int){Date temp(*this);_day += 1;return temp;}
private:int _year;int _month;int _day;
};
int main()
{Date d;Date d1(2022, 1, 13);d = d1++;    // d: 2022,1,13   d1:2022,1,14d = ++d1;    // d: 2022,1,15   d1:2022,1,15return 0;
}
http://www.lryc.cn/news/4628.html

相关文章:

  • 什么是眼图?(扫盲向)
  • 【C++】类与对象(二)
  • 【软考】系统集成项目管理工程师(二十一)项目收尾管理
  • 关于公钥与私钥的一点看法
  • 深入React源码揭开渲染更新流程的面纱
  • 32个关于FPGA的学习网站
  • 5分钟快速上手Promise使用
  • 大客户市场:阿里云、腾讯云、华为云“贴身肉搏”
  • 华为OD机试 - 求字符串中所有整数的最小和(Python)| 真题+思路+代码
  • 企业电子招投标采购系统源码之首页设计
  • 浅谈一下前端工作中全流程多层次的四款测试工具
  • 【运算放大器】反相放大电路仿真应用
  • 数组的操作
  • Python - 文件基础操作
  • react的useState源码分析
  • SharpImpersonation:一款基于令牌和Shellcode注入的用户模拟工具
  • 华为OD机试 - 最大相连男生数(Python)| 真题+思路+代码
  • GIS在地质灾害危险性评估与灾后重建中的实践技术应用及python机器学习灾害易发性评价模型建立与优化
  • 2.13、进程互斥的硬件实现方法
  • Leetcode力扣秋招刷题路-2335
  • C语言深度解剖-关键字(6)
  • [多线程进阶]CAS与Synchronized基本原理
  • 【Linux系统编程】02:文件操作
  • 华为OD机试 - 去除多余空格(Python)| 真题+思路+代码
  • 百趣代谢组学分享,补充α-酮酸的低蛋白饮食对肾脏具有保护作用
  • json对象和formData相互转换
  • 【c++面试问答】常量指针和指针常量的区别
  • Ubuntu18下编译android的ffmpeg经验
  • Spring Security in Action 第十三章 实现OAuth2的认证端
  • 本文章提供中国国界、国界十段线原始数据以及加载方法