195-C++运算符的重载(CComplex复数类的实现)

本文介绍了C++中的运算符重载技术,如何使自定义对象支持像内置类型一样的运算操作。通过一个复数类的实现,详细展示了构造函数、加法运算符重载、前置后置递增运算符重载以及“+=”、“<<”和“>>”运算符的重载方法。此外,还展示了如何通过全局函数作为友元来实现这些重载,确保对象间、整数与对象间的各种运算组合都能正确工作。

1、C++的运算符重载

使对象的运算表现得和编译器内置类型一样

template<typename T>
T sum(T a, T b)
{
	return a+b;//a.operator+(b)
}
  • 如果T是编译器的内置类型的话,编译器对a+b是可以做的。
  • 但是如果T是我们自定义的对象类型,a和b是两个对象,对象和对象之间该怎么相加???编译器是不知道的。
  • 这里就要使用运算符的重载了。
return a+b;//a.operator+(b),a调用自己的加法函数,将b当成传进去

加法运算符的重载函数。

2、复数类的实现(运算符重载)

在这里插入图片描述

2.1、构造函数

在这里,编译器能不能将一个整数变为一个对象?

  • 这里涉及 实参类型 到 形参类型 的类型强制转换!
  • 看编译器有没有提供带整数形参的构造函数 CComplex(int)的构造函数!
    在这里插入图片描述
    是可以的,因为我们写的构造函数可以是三种类型的构造函数
    在这里插入图片描述

2.2、 “+” 重载函数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们要定义一个全局的加法函数,并且在类中定义为类的友元函数:
在这里插入图片描述
在这里插入图片描述
并且,现在可以将类内的 “+” 重载函数 成员方法屏蔽了,全局的 “+” 重载函数更好!
全局的 “+” 重载函数 可以实现 对象 “+” 对象、整数 “+” 对象、对象 “+” 整数


2.3、++和–前置后置运算符重载函数

operator++()表示前置++ operator++(int)表示后置++ 这个int只是为了区分,没有任何作用

在这里插入图片描述

在这里插入图片描述


2.4、“+=”运算符重载函数

在这里插入图片描述
在这里插入图片描述


2.5、“<<” 和 “<<”运算符重载

  • 这个输出<<运算符重载,对象不在左边,所以不可以提供成员方法 (需要对象在左边进行调用),所以定义成全局方法
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

#include <iostream>
using namespace std;

class CComplex
{
public:
	//CComplex() CComplex(20) CComplex(30, 30)
	CComplex(int r = 0, int i = 0)
		:mreal(r), mimage(i) {}

	//指导编译器怎么做CComplex类对象的加法操作
	CComplex operator+(const CComplex &src)
	{
		//写法1: 
		CComplex comp;//局部对象 
		comp.mreal = this->mreal + src.mreal;
		comp.mimage = this->mimage + src.mimage;
		return comp;
		
		//写法2: 
		return CComplex(this->mreal + src.mreal,
			this->mimage + src.mimage);//对象的优化 
	}

	//后置++
	CComplex operator++(int)
	{
		//方法1: 
		//CComplex comp = *this;
		//mreal += 1;
		//mimage += 1;
		//return comp;
		//方法2: 
		return CComplex(mreal++, mimage++);	//返回的是局部对象,返回值用CComplex接收
	}

	//前置++
	CComplex& operator++()
	{
		mreal += 1;
		mimage += 1;
		return *this;	//出函数,*this是存在的,不是局部对象,返回值用CComplex&
	}

	void operator+=(const CComplex& src)
	{
		mreal += src.mreal;
		mimage += src.mimage;
	}

	void show() { cout << "real:" << mreal << " image:" << mimage << endl; }
private:
	int mreal;//实部 
	int mimage;//虚部 

	//这个全局的方法成了这个类的朋友,这个全局方法可以访问这个类的实部和虚部 
	friend CComplex operator+(const CComplex& lhs, const CComplex& rhs);
	friend ostream& operator<<(ostream& out, const CComplex& src);
	friend istream& operator>>(istream& in, CComplex& src);
};

CComplex operator+(const CComplex& lhs, const CComplex& rhs)//加法的全局运算符重载 
{
	return CComplex(lhs.mreal + rhs.mreal, lhs.mimage + rhs.mimage);
}

ostream& operator<<(ostream& out, const CComplex& src)//输出是从左向右运算的 
{
	out << "mreal:" << src.mreal << " mimage:" << src.mimage << endl;
	return out;
}

istream& operator>>(istream& in, CComplex& src)
{
	in >> src.mreal >> src.mimage;
	return in;
}

int main()
{
	CComplex comp1(10, 10);
	CComplex comp2(20, 20);

	//comp1.operator+(comp2) 加法运算符的重载函数
	CComplex comp3 = comp1 + comp2;//左边是对象,优先调用成员方法 ,成员方法没有的话就去找全局方法 
	comp3.show(); 
	CComplex comp4 = comp1 + 20;//左边是对象,优先调用成员方法,成员方法没有的话就去找全局方法 
	//comp1.operator+(20) int->CComplex 编译器会找有没有CComplex(int)生成1个临时对象 ,然后进行相加 
	comp4.show();

	//编译器做对象运算的时候,会调用对象的运算符重载函数(优先调用成员方法);如果没有成员方法
	//就在全局作用域找合适的运算符重载函数
	//  我们在全局提供   ::operator+(30, comp1)  30和comp1都当做实参传进去 
	CComplex comp5 = 30 + comp1;//30在里面必须要有趋势要做类型的转换!!! 无法调用成员方法的加法运算符重载函数 
	//看复数类型有没有带整型参数的构造函数来生成1个临时对象让lhs引用,就生成一个实部是30,虚部是0的临时对象 
	comp5.show();

	//CComplex operator++(int)
	comp5 = comp1++;
	// ++ --是单目运算符  operator++()表示前置++  operator++(int)表示后置++ 这个int只是为了区分,没有任何作用 
	comp1.show();
	comp5.show();
	//CComplex operator++()
	comp5 = ++comp1;
	comp1.show();
	comp5.show();

	//void comp1.operator+=(comp2)   ::operator+=(comp1, comp2)
	comp1 += comp2;

	//comp1.show();//对象信息的输出
	//这个输出<<运算符重载,对象不在左边,所以不可以提供成员方法 ,所以定义成全局方法 
	//cout ::operator<<(cout, comp1) 流对象是不断放,取东西,是变化的,不能加const  
	//void << endl; 因为要连续输出,不能用void作为返回值 
	//连续的输出,应该把cout返回:ostream& operator<<(ostream &out, const CComplex &src)
	//ostream &out,流对象是不断变化的,前面不能加const
	cout << comp1 << endl;
	cin >> comp1 >> comp2;
	cout << comp1 << comp2 << endl;

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ThinkingF

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值