运算符重载详解(四)

6.重载流插入运算符“<<”
对“<<”和“>>”重载的函数形式如下:
istream& operator >> (istream&,自定义类&);
ostream& operator << (istream&,自定义类&);

重载运算符“<<”的函数的第1个参数和函数的类型都必须是ostream&类型(即ostream类对象的引用),第2个参数是要进行输入操作的类。
因此,只能将重载“<<”和“>>”的函数作为友元函数,而不能讲他们定义为成员函数。
问题:为什么重载“<<”和“>>”的函数只能作为友元函数?
因为只有在输出自定义类对象时才能使用重载的运算符,对其他类型的对象是无效的。

例子:

class Complex
{
public:
	Complex(){ real = 0, imag = 0; } //定义构造函数
	Complex(double r, double i){ real = r, imag = i; }//构造函数重载
	Complex operator + (Complex& c2);		//运算符+重载为成员函数
	friend ostream& operator << (ostream&, Complex&); //运算符<<重载为友元函数
private:
	double real;	//实部
	double imag;	//虚部
};
Complex operator + (Complex &c1, Complex &c2)
{
	return Complex(real + c2.real, imag + c2.imag);
}
ostream& operator << (ostream& output, Complex& c)
{
	output << c.real << "+" << c.imag <<"i"<< endl;
	return output;
	/*return output作用:能连续向输出流插入信息,output是ostream类的对象的引用(它是实参cout的引用,或者说output是cout的别名),cout通过传送地址给output,使他们二者共享同一段存储单元,因此,return output;就是return cout;将输出流cout的现状返回,即保留输出流的现状。*/
}//调用函数相当于执行:cout << c.real << "+" << c.imag <<"i" << endl;
int main()
{
	Complex c1(3, 4), c2(5, -10), c3;
	c3 = c1 + c2;    //c1 + c2 解释为operator + (c1,c2);	
	cout << c3;      //等价于:operator<<(cout,c3)
	return 0;
}

问题:什么情况下“<<”是标准类型数据的流插入符,什么情况下是“<<”是重载的流插入符?
如:cout << c3 << 5 <<endl;
有删除线的的调用重载的流插入符,后面两个“<<”不是重载的流插入符,因为它的右侧不是Complex 类对象而是标准类型的数据,是用预定义的流插入符处理的

7.重载流插入运算符“>>”
C++预定义的运算符>>的作用是从一个输入流中提取数据,如cin>>i;表示从输入流中提取一个整数赋给变量i

class Complex
{
public:
	friend ostream& operator << (ostream&, Complex&); //运算符<<重载为友元函数
	friend ostream& operator >> (ostream&, Complex&); //运算符>>重载为友元函数
private:
	double real;	//实部
	double imag;	//虚部
};
ostream& operator >> (ostream& intput, Complex& c)
{
	intput >> c.real>> c.imag;
	return intput;
}
ostream& operator << (ostream& output, Complex& c)
{
	output << c.real;
	if (c.imag >= 0)  //判断虚部是正值还是负值,是正,在虚部前加"+"号
		output << "+";
	output << c.imag;
	return output;
}//调用函数相当于执行:cout << c.real << "+" << c.imag <<"i" << endl;
int main()
{
	Complex c1, c2;
	cin >> c1 >> c2;   //3+6i,4-10i;用cin和>>可以里连续项程序输入Complex类对象的值,没遇到一次<<就调用一次重载运算符>>
	cout << c1 << c2; 
	return 0;
}

使用运算符重载的具体做法:
<1>先确定要重载的的哪一个运算符,想把它用于哪一个类。重载运算符只能把一个运算符用于一个指定的类。不要误以为用一个运算符重载函数就可以适用于所有的类。
<2>在运算符重载中使用引用(reference)的重要性。利用引用作函数的参数可以在调用函数的过程中不用传递值的方式进行虚实结合,而通过传址方式是形参成为实参的别名,因此不生成临时变量(实参的副本),减少了时间和空间的开销。此外,若重载函数的返回值是对象的引用时,返回的不是常量,而是引用所代表的对象,它可以出现在赋值号的左侧而成为左值,可以被赋值或参与其他操作(如保留cout流的当前值以便能连续使用<<输出)。但使用引用时要特别小心,因为修改了引用就等于修改了它所代表的对象。

8.标准类型数据间的转换
转换方式包括隐式类型转换和显式类型转换
隐式类型转换,如:
int i=6; i=7.5+i; 就是隐式类型转换,将i转换为double,相加得13.5,然后再转换为int得13
显式类型转换,如:
C++形式为:类型名(数据)
C语言形式:(类型名)数据

C++保留了c语言的这种用法,提倡采用C++提供的方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章