栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++——运算符的重载

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++——运算符的重载

目录

1.什么是运算符重载?

(1)通过函数来实现复数相加

(2)通过运算符“+”重载来实现复数相加 

(3)通过运算符 “*” “/” 实现复数乘除

(4)重载“=”

2.重载运算符的限制

3.运算符重载函数的总结

4.运算符重载实现前置++与后置++


1.什么是运算符重载?

运算符重载,就是对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型

运算符的重载实际是一种特殊的函数重载,必须定义一个函数,并告诉C++编译器,当遇到该重载的运算符时调用此函数。这个函数叫做运算符重载函数,通常为类的成员函数。

定义运算符重载函数的一般格式:

返回值类型 类名::operator重载的运算符(参数表) {……}

operator是关键字,它与重载的运算符一起构成函数名。因函数名的特殊性,C++编译器可以将这 类函数识别出来。

(1)通过函数来实现复数相加
Complex Add(Complex cx) // 第一种写法
{
Complex tmp(Real + cx.Real, Image + cx.Image);
return tmp;
}

// 这里采用Complex对象的引用而不是对象本身,
// 调用时不再重新分配内存建立一个复制的对象,函数效率会更高。
Complex Add(Complex &cx) // 第二种写法
{
Complex tmp(Real + cx.Real, Image + cx.Image);
return tmp;
}

//而在引用形式参数类型说明前加const关键字,表示被引用的实参是不可改变的,
//如程序员不当心在函数体中重新赋值了被引用的实参, C++编译器会认为出错。
Complex Add(const Complex &cx) // 第三种写法
{
Complex tmp(Real + cx.Real, Image + cx.Image);
return tmp;
}

// 成员函数为常方法,如程序员不当心在函数体中对当前对象重新赋值,
// C++编译器会认为出错。
Complex Add(const Complex &cx) const // 第四种写法
{
Complex tmp(Real + cx.Real, Image + cx.Image);
return tmp;
}

// 不要使用引用返回tmp对象,当函数执行结束后,tmp 对象析构了,
//会产生将亡值
Complex & Add(const Complex &cx) const // 第五种写法
{
Complex tmp(Real + cx.Real, Image + cx.Image);
return tmp;
}

(2)通过运算符“+”重载来实现复数相加 
Complex operator+(const Complex& cx) const
{
Complex tmp(Real + cx.Real, Image + cx.Image);
return tmp;
}

(3)通过运算符 “*” “/” 实现复数乘除
//复数乘法: (a+bi) * (c+di) => (a*c - b*d) +(b*c + a*d)i;
//复数除法: (a+bi) /(c+di)
d = c*c + d*d;
x = (a*c + b*d)/d + (b*c - a*d)i;
Complex Complex::operator*(const Complex & c) const
{//重载*
return Complex(Real*c.Real-Image*c.Image,Real*c.Image+c.Real*Image);
}
Complex Complex::operator/(const Complex & c)
{ //重载/
double d = c.Real*c.Real+c.Image*c.Image ;
return Complex((Real*c.Real+Image*c.Image)/d,(Image*c.RealReal*c.Image)/d) ;
}

(4)重载“=”

在类定义中如果没有显式给出赋值运算符重载函数时,并不是不用赋值函数,而是由系统自动调用 缺省的赋值函数。

//赋值语句重载
Complex & operator=(const Complex& cx)
{
	if (this != &cx)
	{
		this->Real = cx.Real;
		this->Image = cx.Image;
	}
	cout << this << "operator=" << &cx << endl;
}
//c1=c2=c3
//c1=c2.operator=(c3)
//c1=operator=(&c2,c3)

2.重载运算符的限制

(1)不可臆造新的运算符.

(2)不能改变运算符原有的优先级、结合性和语法结构,不能改变运算符操作数的个数.

(3)运算符重载不宜使用过多.

(4)重载运算符含义必须清楚,不能有二义性.

(5)C++允许重载的运算符绝大部分运算符可以重载。
不能重载的运算符只有5个:
成员访问运算符、成员指针访问运算符(*)、域运算符(::)、长度运算符(sizeof)、条件运算符(?:)

(6)重载运算符的函数不能有默认的参数。

(7)重载的运算符必须和用户定义的类型的对象一起使用,其参数至少应有一个是类的对象(或类对象的引用)。

(8)用于类对象的运算符一般必须重载,但有两个例外,运算符“=”和“&”不必用户重载。

(9)从理论上说,可以将一个运算符重载为执行任意的操作。如,将“>”运算符重载为“<”运算,但这样违背了运算符重载的初衷,非但没有提高可读性,反而使人无法理解程序。应当是重载运算符的功能类似于该运算符作用于标准类型时所能实现的功能。

3.运算符重载函数的总结

1、运算符重载函数的函数名必须为关键字operator加一个合法的运算符。在调用该函数时,将右 操作数作为函数的实参。

2、当用类的成员函数实现运算符的重载时,运算符重载函数的参数(当为双目运算符时)为一个 或(当为单目运算符时)没有。运算符的左操作数一定是对象,因为重载的运算符是该对象的成员函数,而右操作数是该函数的参数。

3、单目运算符“++”和“--”存在前置与后置问题。 前置“++”格式为: 返回类型 类名::operator++(){……} 而后置“++”格式为: 返回类型 类名::operator++(int){……} 后置“++”中的参数int仅用作区分,并无实际意义,可以给一个变量名,也可以不给变量名。

4、C++中只有极少数的运算符不允许重载。

 还有 # , ## , // , / * */

4.运算符重载实现前置++与后置++
//返回的是+1操作之后的值的引用,是一个左值
Int &operator ++()//返回的是引用
{
	value += 1;
	return *this;
}
//返回+1操作之前的值的副本,是一个右值
//看起来先使用后+1,实际上它已经+1了,只不过我们使用的是它+1之前的值
Int operator++(int)//返回的是值
{
	Int tmp = *this;
	++* this;//调用前置++
	return tmp;
}

从代码可以看出,前置++比后置++效率高,不用产生临时对象,不用调用拷贝构造函数

后置++运算符重载,注意需要加int来与前置++重载做区分,语法规定

后置++返回的是值而不是引用,因为不可以返回局部变量

后置++是先将a放到寄存器中,返回的是右值

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/934824.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号