指向课堂的指针

时间:2013-05-12 23:57:08

标签: c++ pointers operator-overloading

我一直在尝试编写一个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 ++中的类感到困惑,我真的不明白为什么第一个在特定情况下失败。我将不胜感激任何解释。

提前致谢。

注意: 运算符&lt;&lt;不是问题的根源,但无论如何它是:

friend ostream& operator<<(ostream& out, Fraction& f)
{
    out << f.num << "/" << f.den << endl;
    return out;
}

2 个答案:

答案 0 :(得分:4)

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&参数。这允许在第二个操作数是右值(通常是临时对象)时调用它。

答案 1 :(得分:2)

您的+重载会返回Fraction by-reference 的实例。问题是Fraction的本地实例将在表达式a + b的末尾超出范围,但c仍将保留对内存中该空白点的引用。

按引用返回不是你想要的。在这种情况下,通过返回by- value

来制作副本更合适
Fraction operator +(Fraction& rightOp)
{
    Fraction result;
    result.num = num * rightOp.den + den * rightOp.num;
    result.den = den * rightOp.den;;
    return result;
}

此外,建议您的>>重载通过 Fraction 引用获取const实例,因为它不会在正文中修改它:

friend ostream& operator<<(ostream& out, Fraction const& f)
//                                                ^^^^^