为什么我添加一个“&”,它输出不同?

时间:2019-05-14 13:51:45

标签: c++

我之前(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& operator++(),前者返回一个副本,后者返回原始副本。但是它们的类型均为Fraction。我认为两者都应该叫ostream& operator<<(ostream& os, Fraction&& obj)

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

0.5
10/12
10/12

Fraction&operator ++()输出:

0.5
0.833333
10/12

1 个答案:

答案 0 :(得分:1)

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

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

double

正确的输出流运算符定义为
explicit operator double() { return 1.0* fenzi / fenmu; }
您将其定义为
friend ostream& operator<<(ostream& os, Fraction& obj)

friend ostream& operator<<(ostream& os, Fraction&& obj)是一个右值引用,而不是一个左值引用(Fraction&&)。编译器使用了隐式转换运算符,因为Fraction&(在任一定义中)都返回左值(引用),而不是右值引用(定义为输出流运算符的参数)。

相关问题