自定义类的输出就是使得类可以自带输入输出符号操作,使得类可以方便使用。
如有一个结构体:
struct MyStruct
{
string name;
int num;
};
我们可以定义简单的输出,并把输出格式化为:{"name","num"},如下代码:
ostream& operator<<(ostream& os, const MyStruct &e)
{
return os<<"{\""<<e.name<<"\","<<e.num<<"}";
}
相对应的输入操作就会稍微复杂一点,因为需要检验输入格式是否正确,代码如下:
istream& operator>>(istream& is, MyStruct& e)
{//读入{"name",num}
char c, c2;
if(is>>c&&c=='{'&&is>>c2&&c2=='"')
{
string name;
while(is.get(c)&&c!='"')//读符号,直到遇到"为止
name+=c;
if(is>>c&&c==',')
{
int num=0;
if(is>>num>>c&&c=='}')
{
e.name=name;
e.num=num;//最后赋值给结构体
return is;
}
}
}
is.setf(ios_base::failbit);//标志读入数据流失败
return is;
}
注意is>>操作符是忽略whitespace(白空格符:如空格,回车);而is.get(c)是把白空格符都一起读入的。所以这个代码的name是可以把空格都读入进去的,甚至把回车符号也读进名字里面去。
如:读入格式{"Macheal Jordan",23},输出也是同样格式。
完整测试代码如下:
#include<iostream>
#include<string>
using namespace std;
struct MyStruct
{
string name;
int num;
};
ostream& operator<<(ostream& os, const MyStruct &e)
{
return os<<"{\""<<e.name<<"\","<<e.num<<"}";
}
istream& operator>>(istream& is, MyStruct& e)
{//读入{"name",num}
char c, c2;
if(is>>c&&c=='{'&&is>>c2&&c2=='"')
{
string name;
while(is.get(c)&&c!='"')//读符号,直到遇到"为止
name+=c;
if(is>>c&&c==',')
{
int num=0;
if(is>>num>>c&&c=='}')
{
e.name=name;
e.num=num;//最后赋值给结构体
return is;
}
}
}
is.setf(ios_base::failbit);//标志读入数据流失败
return is;
}
int main()
{
MyStruct myStruct;
myStruct.name="Micheal Jordan,Hello";
myStruct.num=23;
for(;cin>>myStruct;)
cout<<myStruct<<endl;//可以不断读入,知道读入失败为止
return 0;
}
总结:
很方便的一个技术,这也是C++的特色技术之一。
Reference:
The C++ Programming Language 4ed