C++中关于流插入重载流运算符符和流提取重载流运算符符的问题

C++(谭浩强)笔记(第10章)_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
C++(谭浩强)笔记(第10章)
上传于||暂无简介
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
下载文档到电脑,查找使用更方便
还剩5页未读,继续阅读
你可能喜欢重载流插入运算符和流提取运算符
&& &C++ 流插入运算符
流提取运算符 "&&"
&"&&"和"&&"是C++在类库中提供的,所有C++编译系统都在类库中提供输入流类istream
和输出流类 ostream
cin 和 cout 分别是istream和ostream类得对象.在类库提供的头文件中已经对
"&&"进行了重载,使之作为流插入运算符和流提取运算符,能用来输出和输入C++标准类型的数据.
&用户自定义类型的数据,是不能直接用
来输出和输入的.如果想用它们输出和输入自己声明的类型和数据,必须对它们重载.
&对"&&"和"&&"重载的函数形式如下
operator&& (istream&
,自定义类& );
operator&& (ostream&
,自定义类& );
只能将重载"&&" 和
"&&"的函数作为友元函数或普通的函数,而不能将它们定义为成员函数.
#include &iostream&
class Complex
&Complex();
&Complex(double dR,double dI);
&& &Complex
operator+(Complex &r);
&& &friend
operator&&(ostream
&Output,Complex &r);
&& &double
&& &double
Complex::Complex()
&& &dReal =
&& &dImag =
Complex::Complex(double dR,double dI)
&& &dReal =
&& &dImag =
Complex Complex::operator+(Complex &r)
&& &return
Complex(real + r.real,imag + r.imag);
operator&& (ostream
&Output,Complex &r)
&Output&&"("&&r.dReal&&"+"&&r.dImag&&"i)"&&
&& &return
int main()
&& &Complex
obj1(2,5);
&& &Complex
obj2(4,10);
&& &Complex
&& &obj3 =
obj1 + obj2;
&cout&&obj3;
&& &return
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。C++中的标准输入流中,“在每个输入操作之后,流提取运算符返回一个当前对象的引用,就可以连续使用流_百度知道
C++中的标准输入流中,“在每个输入操作之后,流提取运算符返回一个当前对象的引用,就可以连续使用流
就可以连续使用流提取运算符”?还有当前对象指的是谁,是cin还是后面的那个,流提取运算符返回一个当前对象的引用,“在每个输入操作之后C++中的标准输入流中。我的问题就是返回引用与连续使用之间到底是什么关系
提问者采纳
timesCalled&A是个类&&a);&&&&//&&&lt,&//&nbsp,&&&operator&}//&b;&3&&&b);4&&c;&A&nbsp,&&nbsp:cin&nbsp.;operator&& a()()()();&{ int&nbsp.;++a&&&&&c.&&返回了自身引用;&in,简写是;&&amp当前对象指的是【流提取运算符】;a){&2&times&b&(&timesCalled& A();(&nbsp,你实现了下面函数;&&&a(0){} A&c)上面是完整的函数调用形式;,&&return&&&(&Called&&&&timesCalled&operator&nbsp,因此可以连续调用()
cout&&}那么就可以进行如下调用;&&1&a;A&nbsp。比如,那么就可以连续地调用流提取运算符;int&将打印Called&operator&&&gt。你返回了流的引用;*this,&operator&&main(){ A&&lt,&a;a&&&&&&&&nbsp:& }};&amp:istream&&
return&nbsp:struct&()(){&nbsp:A&再举个返回引用来达到连续调用的例子;a;&(istream&&amp
提问者评价
太给力了,你的回答完美地解决了我的问题,非常感谢!
来自团队:
其他类似问题
为您推荐:
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁随笔 - 146&
评论 - 27&
&&&&&&&&&&&
简单版的String类,旨在说明&& &&重载
#include &iostream&
//#include &cstring&//包含char*的字符串处理函数
using namespace
class String
String(){p=NULL;}
String(char *str);
void diaplay();
friend bool operator&(String &str1,String &str2);//重载&操作符
friend ostream & operator &&(ostream&,String &str);
friend istream & operator &&(istream&,String &str);
String::String(char *str)
void String::diaplay()
bool operator&(String &str1,String &str2)
if (strcmp(str1.p,str2.p)&0)
return true;
else return false;
ostream& operator &&(ostream& output,String &str)
output&&str.p;
istream& operator &&(istream& input,String &str)
//input&&str.p;//没有分配空间,无法读入。
str.p=new char[256];
input&&str.p;
char q[256];
//p.length =strlen(q);
str.p=new char[strlen(q)+1];
strcpy(str.p,q);
int main()
String str1("Hello,pig!"),str2;
cin&&str2;
str1.diaplay();
bool b=str1&str2;
cout&&'\n'&&b&&
cout&&str2&&
重载&& &&函数只能作为类的类的友元函数,其形式如下:
istream& operator &&(istream& ,自定义类 &);
ostream& operator &&(ostream& ,自定义类 &);&
重载运算法作为类成员函数还是类友元函数区别:
1 作为类成员函数必须满足运算表达式第一个参数是一个类对象,而且返回值与该对象同类型。
故一般将单目操作符重载为成员函数,双目操作符重载为友元函数。
String 类较完整实现:
#include &iostream&
//#include &cstring&//包含char*的字符串处理函数
using namespace
class String
String(){p=NULL;len=0;}
String(int);
String(char *str);
String (String&);
~String(){delete[]}
void Clear();//清空本串
int mystrlen();
bool IsEmpty();//判断本串是否为空
String Substr(int index,int count);//从index开始提取count个字符的字串
int Find(char c,int start);//从下标start开始找到c后,返回字符c 在本串的下标
char & operator [](int i);//重载[]操作符
operator char *();//将String类对象转换为普通字符串
friend bool operator&(String &str1,String &str2);//重载&操作符
friend ostream & operator &&(ostream&,String &str);
friend istream & operator &&(istream&,String &str);
char *p;//字符串指针
int//字符串长度,不包含最后的\0
String::String(int length)
p=new char[length+1];
String::String(char *str)
if (str==NULL)
len=strlen(str);
p=new char[len+1];
strcpy(p,str);//深拷贝
//p=//只写这个是浅拷贝,只拷贝了指针
String::String(String &other)
len=other.
p=new char[len+1];
strcpy(p,other.p);
bool String::IsEmpty()
return (!this-&len);
void String::Clear()
if (!IsEmpty())
delete[]p;
int String::mystrlen()
int String::Find(char c,int start)
if (start&len) cout&&"超出范围"&&
//return NULL;
for (i =i&++i)
if (p[i]==c) break;
String String::Substr(int index,int count)
if (index+count&len) cout&&"超出范围"&&
String str(count);
for (int i=0;i&i++,index++)
str.p[i]=p[index];
str.p[count]='\0';
char & String::operator[](int i)
if (i&0||i&len-1)
cout&&"越界"&&
return p[i];
//类型转换
String::operator char *()
return (char *)p;
bool operator&(String &str1,String &str2)
if (strcmp(str1.p,str2.p)&0)
return true;
else return false;
ostream& operator &&(ostream& output,String &str)
output&&str.p;
istream& operator &&(istream& input,String &str)
//input&&str.p;//没有分配空间,无法读入。
str.p=new char[256];
input&&str.p;
char q[256];
str.p=new char[strlen(q)+1];
strcpy(str.p,q);
int main()
String str3("hello");
cout&&"\n测试Find功能"&&
pos = str3.Find('e',0);
cout&&str3&&
cout&&pos&&
cout&&"\n测试Substr功能"&&
cout&&str3.Substr(1,2)&&
cout&&"\n测试重载&& &&功能"&&
cout&&"请输入一段字符串"&&
cout&&"测试字符串C函数的应用"&&
String f(40);
char *e = " this is a test";
char g[50]="hahahhah";
strcpy(f,e); //隐含执行了默认类型转换(char *)f;
strcat(g,f);
cout&&"\n测试IsEmpty _strlen功能"&&
String d("tihs is a test");
if(d.IsEmpty())
cout&&"d 是空字符串"&&
cout&&"d 非空字符串 \t长度:"&&d.mystrlen()&&
注意:C++标准库中string类构造函数是浅拷贝,
&string a="hello";&string b(a);&cout&&(void *)a[2]&&&cout&&(void *)b[2]&& 地址形同
注意:operator char *();//将String类对象转换为普通字符串&&
是类型转换函数的定义,即该类型可以自动转换为const char*类型。
像是隐式类型转换
不同于重载*,重载*应写为 char operator * ();
因为运算符重载中有几个运算符的返回值是有格式的(约定),如operator * 在重载时通常返回值是classType&或者const classType& 。operator const char*() const是类型转换函数的定义,即该类型可以自动转换为const char*类型。至于最后一个const,那个大家都知道是对类成员的限制(不允许更改对象的状态)比如我们现在自定一个一个整型(MyInt),它允许在需要使用C++语言中的int类型时将MyInt类型转换为int类型:class MyInt {&&&& public:&&&&&&&&& operator int ()&&&& private:&&&&&&&&&};MyInt::operator int () const{&&&}就可以在需要使用int类型时使用MyInt。需要记住,C++中没有返回类型的函数有3个,构造函数、析构函数、类型转换函数。
前两个是不写返回类型函数实现中也不允许出现return语句最后一个则是不写返回类型,但是必须返回对应类型的值,即必须出现return语句。
类型转换中返回类型在operator后面在括号前面,且没有参数。
函数运算符中是类型在operator 前面
阅读(...) 评论()详解C++编程中的重载流插入运算符和流提取运算符
投稿:goldensun
字体:[ ] 类型:转载 时间:
这篇文章主要介绍了详解C++编程中的重载流插入运算符和流提取运算符,是C语言入门学习中的基础知识,需要的朋友可以参考下
C++的流插入运算符“&&”和流提取运算符“&&”是C++在类库中提供的,所有C++编译系统都在类库中提供输入流类istream和输出流类ostream。cin和cout分别是istream类和ostream类的对象。在类库提供的头文件中已经对“&&”和“&&”进行了重载,使之作为流插入运算符和流提取运算符,能用来输出和输入C++标准类型的数据。因此,凡是用“cout&&”和“cin&&”对标准类型数据进行输入输出的,都要用#include 把头文件包含到本程序文件中。
用户自己定义的类型的数据,是不能直接用“&&”和“&&”来输出和输入的。如果想用它们输出和输入自己声明的类型的数据,必须对它们重载。
对“&&”和“&&”重载的函数形式如下:
istream & operator && (istream &, 自定义类 &);
ostream & operator && (ostream &, 自定义类 &);
即重载运算符“&&”的函数的第一个参数和函数的类型都必须是istream&类型,第二个参数是要进行输入操作的类。重载“&&”的函数的第一个参数和函数的类型都必须是ostream&类型,第二个参数是要进行输出操作的类。因此,只能将重载“&&”和“&&”的函数作为友元函数或普通的函数,而不能将它们定义为成员函数。
重载流插入运算符“&&”
在程序中,人们希望能用插入运算符“&&”来输出用户自己声明的类的对象的信息,这就需要重载流插入运算符“&&”。
[例] 用重载的“&&”输出复数。
#include &iostream&
class Complex
Complex( ){real=0;imag=0;}
Complex(double r,double i){real=r;imag=i;}
Complex operator + (Complex &c2); //运算符“+”重载为成员函数
friend ostream& operator && (ostream&,Complex&); //运算符“&&”重载为友元函数
Complex Complex::operator + (Complex &c2)//定义运算符“+”重载函数
return Complex(real+c2.real,imag+c2.imag);
ostream& operator && (ostream& output,Complex& c) //定义运算符“&&”重载函数
output&&"("&&c.real&&"+"&&c.imag&&"i)"&&
int main( )
Complex c1(2,4),c2(6,10),c3;
注意,在Visual C++ 6.0环境下运行时,需将第一行改为#include &iostream.h&,并删去第2行,否则编译不能通过。运行结果为:
可以看到在对运算符“&&”重载后,在程序中用“&&”不仅能输出标准类型数据,而且可以输出用户自己定义的类对象。用“cout&&c3”即能以复数形式输出复数对象c3的值。形式直观,可读性好,易于使用。
下面对怎样实现运算符重载作一些说明。程序中重载了运算符“&&”,运算符重载函数中的形参output是ostream类对象的引用,形参名output是用户任意起的。分析main函数最后第二行:
运算符“&&”的左面是cout,前面已提到cout是ostream类对象。“&&”的右面是c3,它是Complex类对象。由于已将运算符“&&”的重载函数声明为Complex类的友元函数,编译系统把“cout&&c3”解释为
operator&&(cout, c3)
即以cout和c3作为实参,调用下面的operator&&函数:
ostream& operator&&(ostream& output,Complex& c)
output&&"("&&c.real&&"+"&&c.imag&&"i)"&&
调用函数时,形参output成为cout的引用,形参c成为c3的引用。因此调用函数的过程相当于执行:
cout&&″(″&&c3.real&&″+″&&c3.imag&&″i)″&&
请注意,上一行中的“&&”是C++预定义的流插入符,因为它右侧的操作数是字符串常量和double类型数据。执行cout语句输出复数形式的信息。然后执行return语句。
请思考,return& output的作用是什么?回答是能连续向输出流插入信息。output是ostream类的对象,它是实参cout的引用,也就是cout通过传送地址给output,使它们二者共享同一段存储单元,或者说output是cout的别名。因此,return output就是return cout,将输出流cout的现状返回,即保留输出流的现状。
请问返回到哪里?刚才是在执行
在已知cout&&c3的返回值是cout的当前值。如果有以下输出:
cout&&c3&&c2;
(cout&&c3)&&c2;
而执行(cout&&c3)得到的结果就是具有新内容的流对象cout,因此,(cout&&c3)&&c2相当于cout(新值)&&c2。运算符“&&”左侧是ostream类对象cout,右侧是Complex类对象c2,则再次调用运算符“&&”重载函数,接着向输出流插入c2的数据。现在可以理解了为什么C++规定运算符“&&”重载函数的第一个参数和函数的类型都必须是ostream类型的引用,就是为了返回cout的当前值以便连续输出。
请读者注意区分什么情况下的“&&”是标准类型数据的流插入符,什么情况下的“&&”是重载的流插入符。如
cout&&c3&&5&&
有下划线的是调用重载的流插入符,后面两个“&&”不是重载的流插入符,因为它的右侧不是Complex类对象而是标准类型的数据,是用预定义的流插入符处理的。
还有一点要说明,在本程序中,在Complex类中定义了运算符“&&”重载函数为友元函数,因此只有在输出Complex类对象时才能使用重载的运算符,对其他类型的对象是无效的。如
cout&&time1; //time1是Time类对象,不能使用用于Complex类的重载运算符
重载流提取运算符“&&”
C++预定义的运算符“&&”的作用是从一个输入流中提取数据,如“cin&&i;”表示从输入流中提取一个整数赋给变量i(假设已定义i为int型)。重载流提取运算符的目的是希望将“&&”用于输入自定义类型的对象的信息。
[例] 在上例的基础上,增加重载流提取运算符“&&”,用“cin&&”输入复数,用“cout&&”输出复数。
#include &iostream&
class Complex
friend ostream& operator && (ostream&,Complex&); //声明重载运算符“&&”
friend istream& operator && (istream&,Complex&); //声明重载运算符“&&”
ostream& operator && (ostream& output,Complex& c) //定义重载运算符“&&”
output&&"("&&c.real&&"+"&&c.imag&&"i)";
istream& operator && (istream& input,Complex& c) //定义重载运算符“&&”
cout&&"input real part and imaginary part of complex number:";
input&&c.real&&c.
int main( )
Complex c1,c2;
cin&&c1&&c2;
cout&&"c1="&&c1&&
cout&&"c2="&&c2&&
运行情况如下:
input real part and imaginary part of complex number:3 6↙
input real part and imaginary part of complex number:4 10↙
c2=(4+10i)
以上运行结果无疑是正确的,但并不完善。在输入复数的虚部为正值时,输出的结果是没有问题的,但是虚部如果是负数,就不理想,请观察输出结果。
input real part and imaginary part of complex number:3 6↙
input real part and imaginary part of complex number:4 -10↙
c2=(4+-10i)
根据先调试通过,最后完善的原则,可对程序作必要的修改。将重载运算符“&&”函数修改如下:
ostream& operator && (ostream& output,Complex& c)
output&&"("&&c.
if(c.imag&=0) output&&"+";//虚部为正数时,在虚部前加“+”号
output&&c.imag&&"i)"&& //虚部为负数时,在虚部前不加“+”号
这样,运行时输出的最后一行为c2=(4-10i) 。
可以看到,在C++中,运算符重载是很重要的、很有实用意义的。它使类的设计更加丰富多彩,扩大了类的功能和使用范围,使程序易于理解,易于对对象进行操作,它体现了为用户着想、方便用户使用的思想。有了运算符重载,在声明了类之后,人们就可以像使用标准类型一样来使用自己声明的类。类的声明往往是一劳永逸的,有了好的类,用户在程序中就不必定义许多成员函数去完成某些运算和输入输出的功能,使主函数更加简单易读。好的运算符重载能体现面向对象程序设计思想。
可以看到,在运算符重载中使用引用(reference)的重要性。利用引用作为函数的形参可以在调用函数的过程中不是用传递值的方式进行虚实结合,而是通过传址方式使形参成为实参的别名,因此不生成临时变量(实参的副本),减少了时间和空间的开销。此外,如果重载函数的返回值是对象的引用时,返回的不是常量,而是引用所代表的对象,它可以出现在赋值号的左侧而成为左值(left value),可以被赋值或参与其他操作(如保留cout流的当前值以便能连续使用“&&”输出)。但使用引用时要特别小心,因为修改了引用就等于修改了它所代表的对象。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具

我要回帖

更多关于 c 运算符重载 的文章

 

随机推荐