今天,我给大家来讲运算符重载中流插入运算符和流提取运算符的重载.
首先给大家说一说:
cout<<5<<"this";
这个语句为什么能够成立?
要想知道这个语句为什么能成立,那我们就得知道cout是什么?
你们肯定会说,cout不就是一个简单的输出吗,对确实是输出!
但是这个"<<"为什么能运用到这个cout上面,这不是右移计算符,计算二进制的呀!
当然,这也是运算符重载!
cout是在iostream这个头文件里面定义的,而cout就是一个类,这个类叫做ostream,也是在头文件之中的.
至于"<<"为什么能用在cout身上,大家应该都很清楚了吧,毕竟在iostream头文件里面就已经对"<<"运算符进行了重载
那我们该想了!怎么样的重载才可以使得
cout<<5;
和
cout<<"this";
都可以成立呢?
首先,我们假设这个重载函数一个类的成员函数,就用ostream来说,写一个代码:
void ostream::operator<<(int n){
//......输出n的代码
return ;
}
由于我们没有考虑的过于清楚,所以这个函数的返回值写void也是可以的,虽然有着更好的写法,但是在这个代码里面看,却又无伤大碍.
这个省略的就是输出n的一串代码,但是肯定不是cout什么的输出,C++STL库的设计者有很多办法可以将这个元素输出出去,这里面不在细讲.
写了这个代码,cout<<5就可以继续执行了,但是cout<<"this"还是不行,因为类型都不同,所以我们要再写一个运算符重载的函数.
void ostream::operator<<(char *n){
//......输出n的代码
return ;
}
我们来细微整理一下:
到底怎么搞, 怎么重载,才可以让cout<<5<<"this";成立呢?
我们可以修改一下前面重载运算符的方式,这个连续的输出在void类型里面肯定是不行的,那什么类型才可以呢?自然是cout的类型ostream,我们可以用引用的方式进行返回;
int类型:
ostream &ostream::operator<<(int n){
//......输出n的代码
return *this;
}
char*类型:
ostream &ostream::operator<<(char *n){
//......输出n的代码
return *this;
}
看到以上两个代码,你们可能会疑惑,this是什么?我们没有定义啊?
this就是每一个空间都会自动生成出来的指针,他指向了当前空间里面的类,在这段代码里面,this指的就是ostream这个对象.
这几个重载函数,让我们可以运行cout<<5<<"this";这串代码,那么我们得知道本质上的函数调用的形式是什么?
cout.operator<<(5).operator<<("this");
假设下面这段程序输出结果为"5hello",该补一些什么呢?
Class CStudent{
public:
int nAge;
};
int main(){
CStudent a;
s.nAge=5;
cout<
首先这段程序的右移运算符, 他没有进行重载运算符,所以需要添加重载函数,经过改编,代码变成了这个样子:"
ostream &ostream<<(ostream &o,const Const CStudent &s){
o<
因为o在这个函数,代表的cout是输出的一声
假定c是Complex复数类的对象,现在希望写“cout <
这道题其实不难,难于cin这个输入,而">>"运算符,我们也没有进行重载过,所以要讲的详细一些!
我们可以先写main():
int main(){
Complex c;
int n;
cin>>c>>n;
cout<
然后在写自己的类:
#include
#include
#include
using namespace std;
class Complex{
public:
double real,imag;
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<>(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*指针指向的内容转换到float类型
sTmp=s.substr(pos+1,s.length()-pos-2);
//分离出代表虚部的字符串
c.imag=atof(sTmp.c_str());
return is;
}
在左移运算符中,有很多都是关于string这个类型的各种库函数,由于我们的重点不是这个,我就不细讲了!
#include
#include
#include
using namespace std;
class Complex{
public:
double real,imag;
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<>(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*指针指向的内容转换到float类型
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<
123+123i 81
123+123i,81
这就是我今天学习的类了!