C++重载输出运算符”<<”和输入运算符”>>”

C++重载输出运算符”<<”和输入运算符”>>”

DateAuthorVersionNote
2022.12.17Dog TaoV1.0整理后发表。

前言

在 C++中,左移运算符<<可以和 cout 一起用于输出,因此也常被称为“流插入运算符”或者“输出运算符”。实际上,<<本来没有这样的功能,之所以能和 cout 一起使用,是因为被重载了。

特别说明:本文参考了这篇博文

重载运算符

coutostream 类的对象。ostream 类和 cout 都是在头文件 中声明的。ostream 类将<<重载为成员函数,而且重载了多次。

例如,为了使cout << "Star War"能够成立,ostream 类需要将<<进行如下重载:

ostream & ostream::operator << (const char* s)
{
    //输出s的代码
    return * this;
}

再如,为了使cout << 5能够成立,ostream 类还需要将<<进行如下重载:

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

重载函数的返回值类型为 ostream 的引用,并且函数返回 *this,就使得cout << "Star War" << 5能够成立。这是因为cout << "Star War"这个表达式的值依然是 cout(说得更准确一点就是 cout 的引用),所以能够和<< 5继续进行运算。这个表达式等价于:

(cout.operator<<("Star War")).operator<<(5);

同理,cinistream 类的对象,是在头文件 中声明的。istream 类将>>重载为成员函数,因此 cin 才能和>>连用以输入数据。一般也将>>称为“流提取运算符”或者“输入运算符”。

开发示例

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

显然,要对<<>>进行重载,程序源码如下:

#include <iostream>
#include <string>
#include <cstdlib>

using namespace std;

class Complex
{
    // 没有声明public,private,protected,默认为是private.
    double real,imag;

public:
    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 << c.real << "+" << c.imag << "i"; //以"a+bi"的形式输出
    return os;
}

istream & operator>>(istream & is, Complex & c)
{
    string s;
    is >> s;  //将"a+bi"作为字符串读入, "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 << c << "," << n;
    return 0;
}
  • 因为没有办法修改 ostream 类和 istream 类,所以只能将<<>>重载为全局函数的形式。由于这两个函数需要访问 Complex 类的私有成员,因此在 Complex 类定义中将它们声明为友元cout<<c会被解释成operator<<(cout, c),因此编写operator<<函数时,它的两个参数就不难确定了。
  • 第 13 行的参数 os 只能是 ostream引用,而不能是 ostream 对象,因为 ostream 的复制构造函数是私有的,没有办法生成 ostream 参数对象。operator<< 函数的返回值类型设为 ostream &,并且返回 os,就能够实现<<的连续使用,如cout << c << 5。在本程序中,执行第 34 行的cout<<c进入 operator<< 后,os 引用的就是 cout,因此第 34 行就能产生输出。
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

全能骑士涛锅锅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值