C++流插入运算符和流提取运算符的重载

  今天,我给大家来讲运算符重载中流插入运算符和流提取运算符的重载.

cout为什么能成立?

  首先给大家说一说:

cout<<5<<"this";

  这个语句为什么能够成立?

  要想知道这个语句为什么能成立,那我们就得知道cout是什么?

  你们肯定会说,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;相当于cout.operator<<(5);
  • cout<<"this";相当于cout.perator<<("this");

  到底怎么搞, 怎么重载,才可以让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");

  例题1:

  假设下面这段程序输出结果为"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是输出的一声

  例题2:

  假定c是Complex复数类的对象,现在希望写“cout <>c;”,就能从键盘接受“a+bi”形式的输入,并且使得c.real = a, c.imag = b。

  这道题其实不难,难于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

这就是我今天学习的类了! 

你可能感兴趣的:(C++面向对象编程(类),c++,类,流插入运算符,流提取运算符,重载)