我一直在尝试编写Fraction类并重载其某些运算符(+,-,-,/ ...)。一开始,我尝试这样做:
Fraction& operator+(Fraction& rightOp)
{
Fraction result;
result.num = num * rightOp.den + den * rightOp.num;
result.den = den * rightOp.den;;
return result;
}
这产生了尴尬的结果。在测试时,如果我使用过:
Fraction a(2,3);
Fraction b(4,5);
Fraction c = a + b;
cout << c << endl;
它将正确打印。但是,如果我使用过:
Fraction a(2,3);
Fraction b(4,5);
Fraction c;
c = a + b;
cout << c << endl;
它会打印-858993460 / -858993460。
然后,当我尝试将重载函数更改为:
Fraction& operator+(Fraction& rightOp)
{
Fraction* result = new Fraction;
result->num = num * rightOp.den + den * rightOp.num;
result->den = den * rightOp.den;
return *result;
}
一切都会很好。这让我对指向C ++中的类感到困惑,我不太明白为什么第一个在特定情况下会失败。我将不胜感激。
提前致谢。
注意:
运算符<
friend ostream& operator<<(ostream& out, Fraction& f)
{
out << f.num << "/" << f.den << endl;
return out;
}
最佳答案
Fraction& operator+(Fraction& rightOp)
{
Fraction result;
result.num = num * rightOp.den + den * rightOp.num;
result.den = den * rightOp.den;;
return result;
}
问题在于它正在返回对局部变量的引用。函数结束时将销毁局部变量,因此该引用引用了无效的对象。
使用
new
可以为您解决问题,因为它可以动态分配result
对象。在功能结束时不会破坏此类对象。但是,这里肯定不是解决方案。 operator+
的用户完全不清楚返回的引用是指动态分配的对象,将来需要delete
d。永远不要给您的用户带来负担。相反,您应该更改函数,使其按值返回:
Fraction operator+(Fraction& rightOp)
{
// ...
return result;
}
现在将返回
result
的副本,因此result
是否在函数末尾销毁并不重要。作为附加说明,您可能希望函数采用
const Fraction&
参数。当第二个操作数是一个右值(通常是一个临时对象)时,这将允许调用它。