运算符重载

运算符重载

  • 运算符重载的概念

  • 非类的成员函数实现运算符重载

  • 类的成员函数实现运算符重载

  • 重载运算符的意义

  • 运算符重载的限制

  • 运算符重载的原则

  • 运算符重载的正确姿势

运算符重载的概念

运算符重载的概念

在OOP编程中,万物皆对象,比如我们学习过的std:string对象,能够像普通类型一样实现加减乘除呢

std:string str=“大家好!";

str=str+“才是真的好!";

要实现这个功能我们就要对运算符+重新进行设计,当我们的对象进行+运算时不再是编译器默认的+预算,而是进入我们指定的函数

这种重新设计运算符规则的技术就称为运算符重载

语法:返回类型 operator运算符()

//例如

bool operator<(const Role& role);


class Person
{
	unsigned short Age;
public:
	Person(unsigned short _Age) :Age{ _Age }
	{}
};

int main()
{
	Person Man(20);
	Person Woman(50);
	if(Man<Woman)//报错:没有与这些操作数匹配的<运算符
}

非类的成员函数实现运算符重载


class Person
{
	friend bool operator < (Person& psa, Person& psb);//友元函数使其可以访问类的私有成员
	unsigned short Age;//私有成员变量
public:
	Person(unsigned short _Age) :Age{ _Age }
	{}
};

bool operator < (Person& psa, Person& psb)
{
	return psa.Age < psb.Age;
}

int main()
{
	Person Man(20);
	Person Woman(50);
	if (operator<(Man, Woman))std::cout << "女人年纪大";//写法1:相当于将其看成一个普通函数名
	if (Man<Woman)std::cout << "女人年纪大" << std::endl;  //写法2:直接用小于号
}
————————————————————————————————————————————————————————————————————————————————
//不用友元函数的写法
class Person
{
	unsigned short Age;
public:
	Person(unsigned short _Age) :Age{ _Age }
	{}
	unsigned short GetAge()
	{
		return Age;
	}
};

bool operator < (Person& psa, Person& psb)
{
	return psa.GetAge() < psb.GetAge();
}

类的成员函数实现运算符重载


class Person
{
	unsigned short Age;
public:
	Person(unsigned short _Age) :Age{ _Age }
	{}
	bool operator>(Person& person); //类的成员函数实现运算符重载
};

bool Person::operator>(Person& person)
{
	return Age > person.Age;
}

int main()
{
	Person Man(20);
	Person Woman(50);
	if(Man.operator>(Woman))std::cout << "男人年纪大";//写法一:相当于将其看成普通函数
	if (Man>Woman)std::cout << "男人年纪大" << std::endl;//写法二:直接用>
}

重载运算符的意义

  1. 让类也支持原生的运算比如+-*/

  1. 提升对程序的控制权比如重载new delete new[] delete[]

备注:

运算符重载的主要目的是为了让目标代码更方便使用和维护,而不是提升开发效率,重载运算符未必能提升开发效率

运算符重载的限制

  1. 不能自创运算符比如===,=<>=只能重载现有运算符

  1. 以下运算符不能重载

  • 对象访问运算符.例如 user.hp

  • 作用域解析运算符:: 例如std::cout

  • 求大小的运算符sizeof 例如sizeof(int)

  • 条件运算符 ? : 例如b=a>c?100:200

  1. 不能修改运算符本身的优先级,相关性

  1. 在C++17后,也不能修改运算符的操作数的计算顺序,在C++17前,编译器可以自由选择如何计算(未定义行为)

  1. 除了delete/delete[]和new/new[]外,不能对原生数据类型的其他运算符进行重载,比如把char类型的+定义为-


int operator+(int a, int b)//错误,非成员运算符要求类类型或枚举类型的参数
{}
  1. 除了new和delete以外,其他运算符的arity (运算符关联的操作数的个数或者是关联的参数)一律不能修改

运算符重载的原则

  1. 不要改变运算符本身的意义, 比如把加法重载为减法

  1. 不建议重载 逻辑运算符&& ||,取址运算符& 逗号运算符,

备注:重载后的逻辑运算符将不会进行短路测试,在C++17标准前,编译器可以自由决定先计算左操作数还是右操作数 , 在C++17后计算的顺序规定为先计算左再计算右

短路测试:a&&b,如果a不成立,则不会测试b

运算符重载的正确姿势

语法

  • 二元运算符的重载

利用全局函数 返回类型 operator 运算符 (类型 左操作数, 类型 右操作数)

利用类的成员函数 返回类型 operator 运算符 (类型右操作数)

  • 一元运算符的重载

利用全局函数返回 返回类型 operator 运算符 (类型 操作数)

利用类的成员函数 返回类型 operator 运算符 ()

正确姿势:

  • 有的运算符只能重载为类的成员函数,有些运算符只能重载为全局函数,有些运算符既可以重载为类的成员函数又可以重载为全局函数,

如果一个运算符既可以重载为成员函数又可以重载为全局函数,我们一般推荐重载为类的成员函数,因为类的成员函数可以是虚函数,单全局函数不能是虚函数,

如果这个运算符不修改对象,应该将这个成员函数限定为const

  • 运算符重载的参数一般可以传递值或者引用,大部分情况下,能够传递引用就不要传递值,

对于不会修改的值最好是限定为const,

某些时候要擅用使用右值引用&&作为参数

  • 运算符重载的返回值一般来说可以是任何类型,但是尽量要符合运算符的原意,

比如把>运算符返回指针类型,把+返回bool类型,都不是很好的选择

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值