输入输出(4)——C++的输入输出运算符

目录

一、输入运算符>>

二、输出运算符<<

三、 输入与输出运算符的重载

(一)必须重载为类的友元函数

(二)返回类型应是对象的引用


一、输入运算符>>

输人运算符“>>”也称为流提取运算符,是一个二目运算符,

两个操作数

左操作数是istream类的一个对象

右操作数既可以是一个预定义的变量,也可以是重载了该运算府的类对象。

因此,输人运算符不仅能够识别预定义类型的变量,如果某个类中重载了这个运算符,它也能识别这个类的对象。

在使用输入运算符时需要注意以下几点。

(1)在默认情况下,运算符“>>”跳过空白符,然后读取与输入变量类型相对应的值此,给一组变量输人值时可以用空格或换行符把输入的数值间隔开。

(2)当输入字符串时,运算符“>>”会跳过空白符,因此读取的字符串中不要有空格否则认为是结束

(3)不同类型的变量一起输入时,系统除了检查是否有空白符外,还完成输入数据与变量类型的匹配

如:
int n;
float x;
cin>>n>>x;

如果输人:33.33  22.22

则得到的结果为n=33.  x=0.33.

(4)输入运算符采用左结合方式,可以将多个输人操作组合到一个语句中。

二、输出运算符<<

输出运算符“<<”也称为流插人运算符,是一个二目运算符

两个操作数

左操作数是ostream类的一个对象

右操作数既可以是一个预定义的变量,也可以是重载了该运算符的类对象。

因此,输出运算符不仅能够识别预定义类型的变量,如果某个类中重载了该运算符.它也能识别这个类的对象。
在使用输出运算符时需要注意以下几点。

(1)输出运算符也采用左结合方式,可以将多个输出操作组合到一个语句中。如,

int n=1;
double m=1.1;
cout<<n<< ","<<m<<endl;

输出结果就是:
1,1.1

(2)使用输出运算符时,不同类型的数据也可以组合在一条语句中,编译程序会根据在“<<”右边的变量或常量的类型,决定调用重载该运算符的哪个重载函数,

三、 输入与输出运算符的重载

用户可以通过对输人运算符“>>”和输出运算符“<<”进行重载来支持新的数据类型的输入输出。

如果想用它们输出和输人用户自己定义的类型的数据,就必须对它们进行重载。实际上,运算符“<<”和“>>”已经被重载过很多次了。最初,“<<”和“>>”运算符是(和C++的位运算符。ostream类对“<<”运算符进行了重载,将其转换为一个输出工具cout是ostream类的一个对象,它是智能的,能够识别所有的C++基本类型。这是因为对于每种类型,ostream类声明中都包含了相应的重载函数“operator<<”的定义。因此要使cout能够识别用户自定义类的对象,就要在用户自定义类中对“<<”运算符进行重载,让用户自定义类知道如何使用cout。

在重载时要注意下面两点。

(一)必须重载为类的友元函数


要对“<<”和“>>”运算符进行重载,必须重载为类的友元函数
为什么一定要重载为类的友元函数呢?

定义了一个Point类,假设t是Point的一个对象,为显示Point的值,使用下面的语句:
cout<<t;
这个语句中,使用了两个对象,其中第一个是ostream类的对象(cout)

如果使用一个Point 成员函数来重载“<<”运算符,Point对象(this指针)将是第一个操作数,这就意味着必须这样使用“<<”运算符:
t<<cout;
这样会令人迷惑。但通过使用友元函数,可以像下面这样重载运算符

void operator<<(ostream &out,Point &t)

{ cout<<"("<<t .x<<","<<t ,y<<")"<<endl; }


这样可以使用下面的语句:
cout<<t;

注意:新的“operator<<”定义使用 ostream 类引用 out 作为它的第一个参数。

通常情况下,out 引用 cout 对象,如表达式“cout<<t”所示。但也可以将这个运算符用于其他ostream对象,如cerr,在这种情况下,out将引用相应的对象。

调用“cout<<t”应使用cout对象本身,而不是它的副本,因此该函数按引用(而不是按值)来传递该对象。这样,表达式“cout<<t”将导致out成为cout的一个别名。Point对象可以按值或按引用来传递,因为这两种形式都使函数能够使用对象的值。按引用传递使用的内存和时间都比按值传递少

(二)返回类型应是对象的引用

重载的友元函数的返回类型应是ostream对象或istream对象的引用,即osream&或 istream &

经过声明和定义上面的重载函数,如下面这样的语句:

cout<<t;

可以正常工作,但下面的语句:
cout<< "t= "<<t ;

不能正常的输出。要理解这样做不可行的原因以及必须如何才能使其正常输出,首先看下面的语句:

int x=5,y=6;
cout<< x<< y;
C++从左到右读取输出语句,这意味着它等同于:
(cout<<x)<< y;

正如iostream中定义的那样,“<<”运算符要求左边是一个ostream类的对象。显然,因为cout是ostream对象,所以表达式“cout<<x”满足这种要求。但是,因为表达式“cout<<x”位于“<<y”的左侧,所以输出语句也要求该表达式是一个ostream 类型的对象。因此,ostream 类将“operator<<”函数实现为返回一个ostream对象。具体地说,在这个例子中,它返回调用对象cout。因此,表达式“cout<<x”本身也是一个ostream对象,从而可以位于“<<”运算符的左侧。

可以对上面的“operator<<”友元函数采用相同的方法。只要修改“operator<<”函数,让它返回ostream 对象的引用即可。

ostream& operator<<(ostream &out, Point &t)
{
    out<<"("<<t .x<< ","<<t・y<<")"<<endl;

    return out;
}

注意,返回类型是ostream&。这意味着该函数返回ostream对象的引用。因为函数开始执行时,程序传递一个对象给它,这样做的最终结果是,函数的返回值就是传递给它的对象。也就是说,下面的语句:
cout<<t;
各被转换为下面的调用:
operator<<(cout,t);
而调用返回 cout对象。因此,下面的语句可以正常工作:
cout<<"t= "<<t;

将这条语句分成多步,来看看它是如何工作的。
首先,“cou<<"t="”调用 ostream 类中的"operator<<"定义,它显示字符电并近cout对象。因此表达式“cout<<"="”将显示字符串,然后被它的返回值cout所原来的语句被简化为下面的形式:
cout<<t;

#include<iostream>
using namespace std;
class Date
{
public:
	Date(int x, int y, int z);
	friend ostream& operator<<(ostream& out, Date& date);
private:
	int year;
	int month;
	int day;
};
Date::Date(int x,int y,int z):year(x),month(y),day(z){}
ostream& operator << (ostream & out, Date & date)
{
	out << date.year << '/' << date.month << '/' << date.day << endl;
	return out;
}
int main()
{
	Date d1(1, 1, 1);
	Date D2(1, 2, 3);
	cout << d1 << D2;

	return 0;
}

程序运行结果如下:

1/1/1
1/2/3

  • 8
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值