cout之<< ++运算符重载调用顺序

前言

今天我同学问我这样一个问题:

79f5adee1ef3457ea87eb4ee993d5af9.png

 为什么二三行cout输出的不一样

 于是我结合了一些文章视频与自己的理解,写了这篇文章。

一、cout与<<究竟是什么

<iostream>文件中的std::cout配合左移运算符完成打印

这是cout在<iostream>文件中的定义,是一个ostream对象

_EXPORT_STD extern "C++" __PURE_APPDOMAIN_GLOBAL _CRTDATA2_IMPORT istream cin;
_EXPORT_STD extern "C++" __PURE_APPDOMAIN_GLOBAL _CRTDATA2_IMPORT ostream cout;

 实际上cout是这么一回事:

ostream& operator<<(ostream& cout, Type& a) 

// 我们以cout<<(Type)的形式调用上面的函数

Effective C++一书中说,要以当年C++开发者写内置类型时的态度写自定义类,那么两者必有共同之处。假如我们自定义了一个类Int,里面只有一个int成员变量,我们就需要重载左移运算符:

class Int {
   friend void operator<<(ostream& cout, Int& a);
   friend ostream& operator<<(ostream& cout, Int& a);
            
   public:
    Int(int i)
    : i_(i) {}
    int i_;
};

// cout 属于 ostream 类型
void operator<<(ostream& cout, Int& a)  
{
    cout << a.i_ << endl;
} // 不好,因为这样写,cout << a;合法,但 cout << a << a;不合法

// 为了实现上面没能实现的无限追加输入的链式编程思想,可以像下面这样写
ostream& operator<<(ostream& cout, Int& a)  
{
    cout << a.i_ << endl;
    return cout;
}  // 解决了上面的问题

 然后把它作为int类的友元,这样才有以下的运算:

Int i = 1;  // 单参构造函数,隐式构造
cout << i << i << endl;

到现在,无限追加输入的链式编程,究竟是怎么执行这件事,我们可以略知一二了:

ostream& operator<<(ostream& cout, Type& a)  
{
    // TODO
    /*在这里执行打印操作*/
    return cout;
}

// 以下是“伪代码”

// 事情是这样的:

// 1- << 传入两个参数 cout 和 (type)   -- (type)泛指某种类型的对象
cout << (type) << (type) << (type);
// << 调用结束返回一个 &cout ,cout引用自动解析,就变成了下面的样子 

          // 2- 返回的cout 与第二个(type) 再次作为 << 的参数
          cout << (type) << (type);
          // 再次返回一个 &cout

                  cout << (type);
                  // 这次的返回值&cout没人接收了,于是自动释放返回值。

二、++放左边跟放右边有什么区别

一般来说,前置自增(也就是++放左边)调用速度比后置自增快,原因是前者采用引用传递pass-by-reference而后者采用值传递pass-by-value。

但是在左移运算符链中,两者就有明显的区别,就像我一开始放的那张图一样。

int func1()
{
    cout << "print 1" << endl;
    return 1;
}

int func2()
{
    cout << "print 2" << endl;
    return 2;
}

cout << func1() << func2() << endl;

/*
输出结果:

print 2
print 1
12
*/为什么

 原来,在cout链中,函数从右向左调用,返回值从左往右打印。

结语

假如读者看懂了一、二两大点,那么文章一开始的问题就可以迎刃而解了,快去试一试吧!

我承认上面说的基本上没用,但是对C++内置类型的原理探讨还是很有趣的,何况它还是面试题呢

reference:

[1] cout顺序,i++和++i,*p++和*++p_cout *p-CSDN博客

[2] 41 类和对象-C++运算符重载-递增运算符重载_哔哩哔哩_bilibili

 

 

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值