c++运算符重载与输入输出流重载

运算符重载

运算符重载——赋予运算符具有操作自定义类型数据功能

  •  运算符重载本身也是一种函数,我们有两种写法——友元类运算符重载函数和类运算符重载
  •  运算符重载的实质本身就是函数调用
  • 我们要注意它的写法:
  • 函数返回值 :运算完成后的值决定的               
      函数名    : operator 加上重载运算符组成函数名  例如operator+就是重载加号
       参数      :看运算符的操作数,具体参数个数是要看你重载函数形式是什么
        函数体    : 写运算符具体想要的操作

  对于运算符重载函数的参数友元类函数和类函数是不一样的

  • 友元类的参数个数是操作数的个数

    例如+是双目运算符,使用+的重载函数的参数个数就是两个

  • 类重载函数的参数个数是操作数的个数减一

    因为类重载函数本身还是对象来调用,所以有一个参数就在类内不需要再次传参

 

 我们可以看到我们自己定义的类是没有办法用这些运算符的,现在我们就需要写运算符重载函数来解决这些红色波浪线

class Complex
{
public:
	Complex(int a = 0, int b = 0) :a(a), b(b) {}
	void print()
	{
		cout << a <<"\t" << b << endl;
	}
	friend Complex operator+(Complex& a, Complex& b);  //类内定义类外实现
protected:
	int a;
	int b;
};
Complex operator+(Complex& a, Complex& b) {
	//return Complex(a.a + b.a, a.b + b.b);   //可以直接用无名对象来返回
	Complex c(a.a + b.a, a.b + b.b);         //也可以定义一个临时的类c,然后运算结束后再返回
	return c;                               
}
int main()
{
	Complex one(1, 1);
	Complex two(2, 0);
	Complex three;
	three = one + two;   //这里的three是一个类,所以我们可以推断重载函数的返回是一个类
	three.print();
	/*打印结果
	3	1
	*/
	return 0;
}

这样,我们的加号运算符也就可以使用了(重载函数的函数体是可以根据你的想法来写的,就算你重载加号,实际的实现是相减都可以)

class Complex
{
public:
	Complex(int a = 0, int b = 0) :a(a), b(b) {}
	void print()
	{
		cout << a <<"\t" << b << endl;
	}
	bool operator>(Complex& object) {  //这是类重载,参数个数是操作数减一
		if (this->a > object.a) return 1;
		else if (this->a == object.a && this->b > object.b) return 1;
		else return 0;
	}
protected:
	int a;
	int b;
};

int main()
{
	Complex one(1, 1);
	Complex two(2, 0);
	// 这里是对两个类进行比较,我们可以推断出这是bool类型
	if (two > one) cout << "two比较大" << endl;  
	else cout << "one比较大" << endl;
	/*打印结果
	two比较大
	*/
	return 0;
}

好了,基础的运算符就是这样重载的,而且友元重载和类重载都写了一遍,那么接下来我们来讲一个新的运算符重载

 

流运算符重载

  • cin类型 : istream类的对象

  • cout类型:  ostream类的对象

  • 流运算符 >>   <<

  • 必须采用友元函数形式重载

 

 这个时候我们就需要用一种特殊的运算符重载——流运算符重载

但是我们又发现了一个问题,这种特殊的重载函数它的类型是什么呢,它该返回什么呢?

当我们不知道返回类型可以先用void类型试试,然后遇到问题再做思考 

class MM {
public:
	MM(string name="",int age=18):name(name),age(age){}
	friend void operator>>(istream& in, MM& a);
	friend void operator<<(ostream& out, MM& a);
protected:
	string name;
	int age;
};
void operator>>(istream& in, MM& a) {  //这是输入的重载函数
	in >> a.name >> a.age;
}
void operator<<(ostream& out, MM& a) {  //这是输出的重载函数
	out << a.name << "\t" << a.age;
}
int main()
{
	MM mm;  
	cin >> mm;   
 	cout << mm;
	/*输入:baby 22
	  打印结果
	  baby    22
	*/
	return 0;
}

这里一定要记住输入输出流运算符重载函数一定要用友元类重载

我们又发现问题了,我们平时的输出不都是习惯写cout<<"  "<<endl;吗,那么我们写的着重载函数可不可以这样操作,或者说我想一次性输入多个数据

 

显然我们是没有办法做到这样的效果的,现在我们要从输入输出流重载函数去考虑了 

 

 所以我们就知道了输入输出流重载函数的返回应该是cin和cout本身

class MM {
public:
	MM(string name="",int age=18):name(name),age(age){}
	friend istream& operator>>(istream& in, MM& a);
	friend ostream& operator<<(ostream& out, MM& a);
protected:
	string name;
	int age;
};
istream& operator>>(istream& in, MM& a) {  //这是输入的重载函数
	in >> a.name >> a.age;                //这里一定要用引用函数,因为要返回流本身
	return in;
}
ostream& operator<<(ostream& out, MM& a) {  //这是输出的重载函数
	out << a.name << "\t" << a.age;
	return out;
}
int main()
{
	MM mm;  
	MM girl;
	cin >> mm>>girl;
	cout << mm <<"\t" << girl << endl;
	/*输入:小红 18
			小丽 20
     打印结果
	 小红    18      小丽    20
	*/
	return 0;
}

我们今天讲的两种运算符重载就到这里,下面还会有各种特殊运算符重载和注意事项

总之运算符重载很多东西是没有为什么的,是需要我们记住的 

  • 22
    点赞
  • 143
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值