问题来源:
cout<<5<<"this"<<endl;
这条语句为什么能够成立呢
平常敲代码的时候只知道要想使用cin,cout需要包含头文件,其实cin是istream类的一个对象,cout是ostream的一个对象,而<<和>>分别是在类中重载运算符
先考虑:下面这条语句
cout<<5;
假设ostream类中的<<运算符重载成员函数是这样定义的
void ostream::operator<<(int n)
{
……//输出N的代码
return ;
}
cout<<5;//等价于cout.operator(5);
类似的对于输出字符串只需将形参换为char *,但是又遇到了新问题,我们希望可以这样
cout<<5<<"this"<<endl;
那么重载函数的返回值肯定就不会是void了,直观的想到如果cout<<5的返回值还是cout,接下来就可以继续cout<<"this"了。重载函数可修改为:
ostream &ostream::operator<<(int n){
……//输出n的语句
return *this;
}
cout<<5<<"this";//等价于cout.operator<<(5).operator<<("this");
假定下面程序输出为5hello,该补些什么呢?
class CStudent{
public:
int nAge;
};
int main(){
CStudent s;
s.nAge=5;
cout<<s<<"Orz"<<endl;
return 0;
}
可以将<<重载为一个全局函数,不能重载为成员函数,因为在ostream类中已经重载过了
ostream &operator<<(ostream &o,const CStudent &s ){
o<<s.nAge;
}
从这里面可以看出,重载同一运算符可以多次,只要函数参数列表不一样,函数调用时会根据参数选择
分隔符
问题:假如c是Complex的复数类的对象,希望写“cout<<c;”就能以"a+bi"的形式输出c的值,写"cin>>c;"就能从键盘以"a+bi"的形式读入c的值,c.real=a,c.imag=b;实现如下:
class Complex{
double real,imag;
public:
Complex(double r=0,double i=0):real(r),imag(i){}
friend ostream & operator<<(ostream & os, const Complex &c);
friend istream & operator>>(istream & is,Complex & c);
};
ostream & operator<<(ostream & os,const Complex &c){
os << c.real << '+' << c.imag << 'i';//以"a+bi"的形式输出
return os;
}
istream & operator>>(istream & is,Complex & c){
string s;
is >> s;//将"a+bi"作为字符串读入,中间能有空格
int pos = s.find('+',0);
string stmp = s.substr(0, pos);//分离出代表实部的字符串
c.real = atof(stmp.c_str());//atof库函数能将const char *指针指向内容转成flost
stmp = s.substr(pos + 1, s.length() - pos - 2);//分离出代表虚部的字符串
c.imag = atof(stmp.c_str());
return is;
}
int main() {
Complex c;
int n;
cin >> c >> n;
cout << c << ',' << n << endl;
return 0;
}
输入和输出
13.2+133i 87
13.2+133i,87