这一节解决了我前面遇到的操作符重载的问题而不能显示类对象的数据,以及输出的显示顺序问题。
好的让我们开始总结这一节所学
- 为什么有要重载iostream运算符?
因为我们想对某个类对象进行读写操作。不重载iostream类运算符直接cout<<类对象<<endl;
或cin>>类对象;
编译器会报错
重载ostream运算符
直接cout<<类对象<<endl;
编译器会报错,所以我们要有个重载的<<运算符函数,比如:
ostream& operator<<(ostream &os,const Triangular &rhs)
{
os<<"("<<rhs.beg_pos()<<","
<<rhs.legnth()<<")";
rhs.display(rhs.length(),rhs.beg_pos(),os);
return os;
//传入重载运算符函数的ostream对象又被原封不动地返回
}
这就是重载的<<运算符,内部的实现是输出什么东西,这个由你自己设定,就按照如代码所示的设定仿写就可以。ostream对象没有被声明为const,是因为每一次输出操作都会更改ostream对象的内部状态(查资料可详细了解如何更改ostream对象的内部状态。
被输出的对象被声明为const是可以的。
我们使用了&,是基于效率考虑而非为了修改其对象内容。
- 好的,定义了重载<<运算符的函数,现在让我们定义并初始化一个类对象,然后输出这个类对象的东西(相关数据)
Triangular tri(6,3);
cout<<tri<<endl;
输出结果:(3,6) 6 10 15 21 28 36
- 你可能有疑问,为什么不把输出(<<)运算符设计为一个成员函数呢?(我没有这个疑问,我本来就觉得重载<<运算符应该服务于所有类的类对象)
- 因为如果把<<运算符函数设计为成员函数,那么<<的左操作数就必须是和<<运算符函数属于同一个类的类对象。我举个例子,比如<<运算符被设计为tri类对象的类成员函数,那么tri类对象就得放在<<运算符的左侧:
tri<<cout<<'\n';
奇不奇怪,适应吗?那所以把<<运算符函数设计成非成员函数的函数多好啊!
重载istream运算符
- 和ostream运算符一样,你可以在重载运算符函数内部设定你要读取什么,举个例子:
istream& operator>>(istream &is,Triangular &rhs)
{
char ch1,ch2;//定义两个字符用来规定
//>>运算符后的输入格式,像scanf函数里可规定输入格式那样
int bp,len;//起始位置和数列长度的定义
is>>ch1>>bp>>ch2>>len;
//假设输入为(3,6) 6 10 15 21 28 36
//那么ch1=='(',bp==3,ch2==',',len==6。
rhs.beg)pos(bp);
rhs.length(len);
rhs.next_reset();
//输入的数据对应传给传进来的类对象(rhs)的数据成员。
return is;
//传入重载运算符函数的istream对象又被原封不动地返回
}
现在,让我们把最后那点问题给解决掉吧!
main.cpp
#include<iostream>
#include<vector>
#include"Triangular.h"
using namespace std;