【问题标题】:C++ iostream operator overladed function return typeC++ iostream 运算符重载函数返回类型
【发布时间】:2015-06-03 00:00:00
【问题描述】:

我仍处于学习 C++ 基本格式和命令的阶段。 我现在在类运算符函数重载中,来到<<>>。我的问题是:当它们在以下朋友函数中定义时:

ostream &operator << ( ostream &output, const PhoneNumber &number )

并使用 PhoneNumber 类 phone 调用,如下所示:

cout << phone << endl;

为什么朋友功能返回ostream&amp;?我的意思是当一个函数返回一个特定类型的值时,它通常由一个基本类型变量接收,例如 bool、int、char、string 等。但是,对于ostreamistream,返回的类型为ostream&amp; 未保存。那么,在这种情况下,它不应该是无效的(执行任务并终止而不返回任何值)吗?

【问题讨论】:

    标签: c++ return operator-overloading iostream


    【解决方案1】:

    因为否则您可以将调用链接到operator&lt;&lt;。这个:

    cout << phone << endl;
    

    被解析为:

    (cout << phone) << endl;
    

    并解析为:

    operator<<(cout, phone).operator<<(endl);
    

    所以它首先调用operator&lt;&lt;(cout, phone),返回cout,然后允许第二个&lt;&lt;调用cout.operator&lt;&lt;(endl)

    如果 operator&lt;&lt; 返回例如void,第二个&lt;&lt; 会尝试调用operator&lt;&lt;(void, endl),但无法编译。

    【讨论】:

      【解决方案2】:

      为什么友元函数返回ostream&?

      允许将运算符链接在一起。运算符返回对传入的同一流的引用。没有该返回引用,您将无法在 cout &lt;&lt; phone 的返回值上调用 &lt;&lt; endl

      我的意思是当一个函数返回一个特定类型的值时,它通常被一个基本类型变量接收,例如 bool、int、char、string 等。

      这是可选的。如果没有将返回值分配给变量以延长其生命周期,则返回值是临时的,并且在语句末尾超出范围。

      但是,对于 ostream 和 istream,没有保存返回的 ostream& 类型。

      不必如此。如果还没有达到最终的;,它只需要存活足够长的时间才能调用下一个操作员。

      那么,在这种情况下,它不应该是无效的(执行任务并终止而不返回任何值)吗?

      没有。

      【讨论】:

      • @Remy Lebeau:谢谢你的回答。现在很清楚了。我已经太习惯于保存返回值,而忽略了它不是强制性的事实。顺便问一下,您能否解释一下为什么返回和输入 ostream 类型应该是引用?他们可能只是普通的副本吗?所以原型是'ostream operator
      • @GrinNare:如果它们不是引用,那么每个操作员调用都会创建一个流的新副本,也就是说给定流是否将状态信息从一个副本保存到下一个副本。请记住,一些运算符接受操纵器作为输入来修改流的状态。在单个流对象上调用许多运算符和操纵器并不罕见。因此,传递引用不仅效率更高,而且是首选,这样他们就知道他们是在原始流上操作,而不是在它的第 N 个副本上操作。
      • @Remy Lebeau:再次感谢您的回复。对于 ++a 或 --a 等运算符,我发现传递引用更有意义。但是,在这种特定情况下,除了效率问题之外,我在流式传输对象副本(相同的最终结果)方面没有看到任何问题,对吗?我完全同意使用一般参考,但我只是要求确认我的理解。
      • @GrinNare:你忽略了我所说的关于流状态和I/O manipulators 的内容。如果不使用引用,操纵器将操纵流的副本,而不是原始流。将多个操纵器链接在一起的情况并不少见,然后将所有修改的累积效果应用于一个流式值。如果随处使用副本,您将失去该能力。状态信息必须从一个运算符传递到另一个运算符,最好通过引用而不是值传递流来执行此操作。
      • @Remy Lebeau:嗯...我不太确定我是否 100% 关注,因为我没有牢牢掌握“流媒体”和“操纵器”。但是,我相信您在复制流时可能不会复制流上的“某些操作”。这可能会导致意想不到的结果。它是否正确? ;(
      【解决方案3】:

      “为什么好友函数返回ostream&amp;?”

      使调用链的这一部分工作

      phone << endl;
      

      ostream&amp; 引用通过所有这些函数调用传递,因此可以在结果上再次调用 operator&lt;&lt;() 函数。

      【讨论】:

        猜你喜欢
        • 2015-01-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-26
        • 1970-01-01
        • 2015-04-26
        • 1970-01-01
        相关资源
        最近更新 更多