【问题标题】:Why I add an "&" ,it outputs different?为什么我添加一个“&”,它输出不同?
【发布时间】:2019-10-01 13:55:43
【问题描述】:

我之前曾问过类似的问题 (Why the code doesn't work on CodeBlocks,but on VS works)。
现在一个新的错误让我很困惑。

cout << ++a1 << endl; 将调用函数operator double()

如果在代码Fraction& operator++() 中我删除& 使其成为Fraction operator++(),它将调用ostream& operator<<(ostream& os, Fraction&& obj)

#include <iostream>
using namespace std;
class Fraction
{
private:
    int fenzi, fenmu;
public:
    Fraction(int a, int b) :fenzi(a), fenmu(b) {}
    operator double()
    {
        return 1.0* fenzi / fenmu;
    }
    friend ostream& operator<<(ostream& os,  Fraction&& obj)
    {
        os << obj.fenzi << "/" << obj.fenmu;
        return os;
    }
    Fraction& operator++()
    {
        fenzi++;
        fenmu++;
        return *this;
    }
    Fraction operator++(int)
    {
        Fraction tmp(fenzi, fenmu);
        fenzi++;
        fenmu++;
        return tmp;
    }
};
int main()
{
    Fraction a1(9, 11), a2(1, 2);
    cout << double(a2) << endl;
    cout << ++a1 << endl;
    cout << a1++ << endl;
    return 0;
}

我想知道为什么输出不同?

Fraction operator++()Fraction&amp; operator++(),前者返回复制的,后者返回原始的。但它们的类型都是Fraction。我认为它应该都叫ostream&amp; operator&lt;&lt;(ostream&amp; os, Fraction&amp;&amp; obj)

分数运算符++() 输出(我预期):

0.5
10/12
10/12

分数和运算符++() 输出:

0.5
0.833333
10/12

【问题讨论】:

  • 请包括实际和预期输出
  • 不知道为什么你会感到困惑。您不能将左值引用传递给右值引用。
  • this 链接可能会回答您的问题。
  • 如果你想让++a1 参数绑定到Fraction&amp;&amp; 参数,这样做:cout &lt;&lt; std::move(++a1) &lt;&lt; endl; 将左值转换为右值,可以绑定到右值参考。
  • 总之Fraction&返回一个左值,Fraction返回一个右值,对吧?

标签: c++


【解决方案1】:
operator double()
{
    return 1.0* fenzi / fenmu;
}

是隐式转换运算符。将explicit 关键字添加到operator double() 将对此有所帮助,因为编译器不会将Fraction 隐式转换为double,除非您将其显式转换为double。添加的内容如下所示:

explicit operator double()
{
    return 1.0* fenzi / fenmu;
}

正确的输出流运算符定义为
friend ostream&amp; operator&lt;&lt;(ostream&amp; os, Fraction&amp; obj)
您将其定义为
friend ostream&amp; operator&lt;&lt;(ostream&amp; os, Fraction&amp;&amp; obj)

Fraction&amp;&amp; 是右值引用而不是左值引用 (Fraction&amp;)。编译器使用隐式转换运算符,因为operator++(在任一定义中)返回左值(引用)而不是定义为输出流运算符参数的右值引用。

【讨论】:

  • 位移运算符在技术上可能与用于输出的流相同,但它们的使用决定了它们的声明方式不同。值得注意的是,第一个参数不能真的是const,返回类型必须是引用类型。
  • 如何将显式关键字添加到运算符 double() 中?总之 Fraction& 返回一个左值,Fraction 返回一个右值,对吧?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-14
  • 2021-01-08
  • 2023-01-22
  • 2022-07-06
  • 1970-01-01
  • 1970-01-01
  • 2020-10-01
相关资源
最近更新 更多