我正在尝试制作一个结构
Fraction
。我已经为其定义了构造函数以及 operator>>
和 operator<<
,并且可以正常工作。
当我定义
operator+
时,我的代码收到以下错误消息:
无法将“Fraction&”类型的非常量左值引用绑定到“Fraction”类型的右值
这是我的代码:
struct Fraction
{
int a;
int b;
Fraction()
{
a = 0;
b = 1;
}
Fraction(Fraction& f)
{
a = f.a;
b = f.b;
}
Fraction(int x, int y)
{
a = x;
b = y;
if (b < 0)
{
b *= -1;
a *= -1;
}
}
};
istream & operator>>(istream & in, Fraction & f)
{
...
return in;
}
ostream & operator<<(ostream & out, Fraction f)
{
if (f.b == 1 || f.a == 0)
out << f.a;
else
out << f.a << "/" << f.b;
return out;
}
Fraction operator+(Fraction f1, Fraction f2)
{
Fraction f((f1.a * f2.b) + (f2.a * f1.b), f1.b * f2.b);
return f;
}
int main()
{
Fraction a, b;
cin >> a >> b;
cout << a + b << endl;
}
如果我更改最后一部分并编写此内容,它就可以正常工作:
int main()
{
Fraction a, b, c;
cin >> a >> b;
c = a + b;
cout << c << endl;
}
我根本不明白为什么会发生这种情况,我想弄清楚。
我只是一个初学者,我知道这个问题可能是愚蠢而明显的。您能否解释一下什么是左值和右值、如何使用它们以及如何更正代码?我已经读过一些有关此的文章,但我仍然不明白这一切与我的情况有何关系。
对非常量对象的引用不能绑定到临时对象。这就是编译器抱怨的地方。
表达式
a + b
返回一个临时对象,然后将其传递给 operator<<
。您的 operator<<
接受一个 Fraction
对象 by value,因此传递给它的任何内容都需要编译器创建一个新的 Fraction
对象。但是,您的 Fraction
复制构造函数不接受临时对象作为输入,因此会出现编译器错误。
您需要:
完全省略复制构造函数,让编译器为您创建一个默认构造函数。
更改复制构造函数以接受对 const 对象的引用,例如:
Fraction(const Fraction& f)
{
a = f.a;
b = f.b;
}
无论哪种方式,您的
operator<<
和 operator+
都应将其输入作为 const 引用,例如:
ostream& operator<<(ostream &out, const Fraction& f)
{
if (f.b == 1 || f.a == 0)
out << f.a;
else
out << f.a << "/" << f.b;
return out;
}
Fraction operator+(const Fraction& f1, const Fraction& f2)
{
Fraction f((f1.a * f2.b) + (f2.a * f1.b), f1.b * f2.b);
return f;
}