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


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

    cout为什么能成立?

      首先给大家说一说:

    cout<<5<<"this";

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

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

      你们肯定会说,cout不就是一个简单的输出吗,对确实是输出!

      但是这个"<<"为什么能运用到这个cout上面,这不是右移计算符,计算二进制的呀!

      当然,这也是运算符重载!

    cout的定义:

      cout是在iostream这个头文件里面定义的,而cout就是一个类,这个类叫做ostream,也是在头文件之中的.

      至于"<<"为什么能用在cout身上,大家应该都很清楚了吧,毕竟在iostream头文件里面就已经对"<<"运算符进行了重载

      那我们该想了!怎么样的重载才可以使得

    cout<<5;

      和

    cout<<"this";

    都可以成立呢?

    "<<"运算符重载

     首先,我们假设这个重载函数一个类的成员函数,就用ostream来说,写一个代码:

    1. void ostream::operator<<(int n){
    2. //......输出n的代码
    3. return ;
    4. }

      由于我们没有考虑的过于清楚,所以这个函数的返回值写void也是可以的,虽然有着更好的写法,但是在这个代码里面看,却又无伤大碍.

      这个省略的就是输出n的一串代码,但是肯定不是cout什么的输出,C++STL库的设计者有很多办法可以将这个元素输出出去,这里面不在细讲.

      写了这个代码,cout<<5就可以继续执行了,但是cout<<"this"还是不行,因为类型都不同,所以我们要再写一个运算符重载的函数. 

    1. void ostream::operator<<(char *n){
    2. //......输出n的代码
    3. return ;
    4. }

      我们来细微整理一下:

    • cout<<5;相当于cout.operator<<(5);
    • cout<<"this";相当于cout.perator<<("this");

      到底怎么搞, 怎么重载,才可以让cout<<5<<"this";成立呢?
      我们可以修改一下前面重载运算符的方式,这个连续的输出在void类型里面肯定是不行的,那什么类型才可以呢?自然是cout的类型ostream,我们可以用引用的方式进行返回;

    int类型:

    1. ostream &ostream::operator<<(int n){
    2. //......输出n的代码
    3. return *this;
    4. }

    char*类型: 

    1. ostream &ostream::operator<<(char *n){
    2. //......输出n的代码
    3. return *this;
    4. }

      看到以上两个代码,你们可能会疑惑,this是什么?我们没有定义啊?

      this就是每一个空间都会自动生成出来的指针,他指向了当前空间里面的类,在这段代码里面,this指的就是ostream这个对象.

      这几个重载函数,让我们可以运行cout<<5<<"this";这串代码,那么我们得知道本质上的函数调用的形式是什么?

      cout.operator<<(5).operator<<("this");

      例题1:

      假设下面这段程序输出结果为"5hello",该补一些什么呢?

    1. Class CStudent{
    2. public:
    3. int nAge;
    4. };
    5. int main(){
    6. CStudent a;
    7. s.nAge=5;
    8. cout<"Hello";
    9. return 0;
    10. }

    首先这段程序的右移运算符, 他没有进行重载运算符,所以需要添加重载函数,经过改编,代码变成了这个样子:"

    1. ostream &ostream<<(ostream &o,const Const CStudent &s){
    2. o<
    3. return 0;
    4. }

      因为o在这个函数,代表的cout是输出的一声

      例题2:

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

      这道题其实不难,难于cin这个输入,而">>"运算符,我们也没有进行重载过,所以要讲的详细一些!

      我们可以先写main(): 

    1. int main(){
    2. Complex c;
    3. int n;
    4. cin>>c>>n;
    5. cout<","<
    6. return 0;
    7. }

    然后在写自己的类:  

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. class Complex{
    6. public:
    7. double real,imag;
    8. Complex(double r=0,double i=0):real(r),imag(i){ };
    9. friend ostream& operator<<(ostream &os,const Complex &c);
    10. friend istream& operator>>(istream &is,Complex &c);
    11. };
    12. ostream &operator<<(ostream& os,const Complex &c){
    13. os<"+"<"i";
    14. return os;
    15. }
    16. istream &operator>>(istream &is,Complex &c){
    17. string s;
    18. is>>s; //将"a+bi"作为字符串读入
    19. int pos=s.find("+",0);
    20. string sTmp=s.substr(0,pos);//分代表实部的字符串
    21. c.real=atof(sTmp.c_str());
    22. //atof库函数能将const char*指针指向的内容转换到float类型
    23. sTmp=s.substr(pos+1,s.length()-pos-2);
    24. //分离出代表虚部的字符串
    25. c.imag=atof(sTmp.c_str());
    26. return is;
    27. }

    在左移运算符中,有很多都是关于string这个类型的各种库函数,由于我们的重点不是这个,我就不细讲了!

    全部代码:
     

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. class Complex{
    6. public:
    7. double real,imag;
    8. Complex(double r=0,double i=0):real(r),imag(i){ };
    9. friend ostream& operator<<(ostream &os,const Complex &c);
    10. friend istream& operator>>(istream &is,Complex &c);
    11. };
    12. ostream &operator<<(ostream& os,const Complex &c){
    13. os<"+"<"i";
    14. return os;
    15. }
    16. istream &operator>>(istream &is,Complex &c){
    17. string s;
    18. is>>s; //将"a+bi"作为字符串读入
    19. int pos=s.find("+",0);
    20. string sTmp=s.substr(0,pos);//分代表实部的字符串
    21. c.real=atof(sTmp.c_str());
    22. //atof库函数能将const char*指针指向的内容转换到float类型
    23. sTmp=s.substr(pos+1,s.length()-pos-2);
    24. //分离出代表虚部的字符串
    25. c.imag=atof(sTmp.c_str());
    26. return is;
    27. }
    28. int main(){
    29. Complex c;
    30. int n;
    31. cin>>c>>n;
    32. cout<","<
    33. return 0;
    34. }

    输入输出结果:

    1. 123+123i 81
    2. 123+123i,81

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

  • 相关阅读:
    【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