今天,我给大家来讲运算符重载中流插入运算符和流提取运算符的重载.
首先给大家说一说:
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<
"Hello"; - return 0;
- }
首先这段程序的右移运算符, 他没有进行重载运算符,所以需要添加重载函数,经过改编,代码变成了这个样子:"
- ostream &ostream<<(ostream &o,const Const CStudent &s){
- o<
- return 0;
- }
因为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<
","< - return 0;
- }
然后在写自己的类:
- #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<
"+"<"i"; - 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*指针指向的内容转换到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<
"+"<"i"; - 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*指针指向的内容转换到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;
-
-
相关阅读:
【Effective C++ 笔记】( 三 )资源管理
JMeter 扩展开发:自定义 Java Sampler
day43
BetterZip for Mac2024最新mac解压缩软件
Oracle 数据库中的全文搜索
对比四大智能合约语言:Solidity 、Rust 、 Vyper 和 Move
一个 MySQL 隐式转换的坑,差点把服务器整崩溃了
淘宝/天猫API:brand_cat-获取品牌分类列表
Linux 系统目录结构
Spring—AOP
-
原文地址:https://blog.csdn.net/wo_ai_luo_/article/details/127754835