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

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

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

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

1、C++的运算符重载

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

template
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 
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;
}

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

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

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