【问题标题】:Making "cout << obj1 + obj2 << endl;" work制作“cout << obj1 + obj2 << endl;”工作
【发布时间】:2013-07-29 15:20:14
【问题描述】:

所以,我得到了 obj1 + obj2 的类内运算符重载:

fraction operator+ (fraction op);

同样,cout

ostream& operator<< (ostream& os, fraction& frac);

但是,如果我尝试将两者结合起来,一切都会崩溃。

fraction.cpp:77:27: error: no match for ‘operator<<’ in 
‘std::operator<< [with _Traits = std::char_traits<char>]((* & std::cout), ((const char*)"Sum: ")) 
<< f1.fraction::operator+(f2)’

代码如下:

#include <iostream>
using namespace std;

class fraction
{
    private:
        int n, d;

    public:
        fraction ()
        {
            this->n = 1;
            this->d = 0;
        }

        fraction (int n, int d)
        {
            this->n = n;
            this->d = d;
        }

        int getNumerator ()
        {
            return n;
        }

        int getDenominator ()
        {
            return d;
        }

        fraction operator+ (fraction op)
        {
            return *(new fraction(this->n*op.d + op.n*this->d, this->d*op.d));
        }

        fraction operator- (fraction op)
        {

            return *(new fraction(this->n*op.d - op.n*this->d, this->d*op.d));
        }

        fraction operator* (fraction op)
        {
            return *(new fraction(this->n*op.n, this->d*op.d));
        }

        fraction operator/ (fraction op)
        {
            return *(new fraction(this->n*op.d, this->d*op.n));
        }
};

ostream& operator<< (ostream& os, fraction& frac)
{
    int n = frac.getNumerator();
    int d = frac.getDenominator();

    if(d == 0 && n == 0)
        os << "NaN";
    else if(d == 0 && n != 0)
        os << "Inf";
    else if(d == 1)
        os << n;
    else
        os << n << "/" << d;
}

int main ()
{
    fraction f1(2, 3);
    fraction f2(1, 3);

    cout << f1 << " " << f2 << endl;

    /*
    cout << "Sum: " << f1+f2 << endl;
    cout << "Difference: " << f1-f2 << endl;
    cout << "Product: " << f1*f2 << endl;
    cout << "Quotient: " << f1/f2 << endl;
    */

    return 0;
}

帮助。 D:

【问题讨论】:

  • 你在疯狂地泄漏内存!将return *(new fraction(...)); 替换为return fraction(...);
  • 停止使用new。可能摆脱您当前的学习材料以支持a decent one
  • 如果你想获取一个对象,不要使用return *(new T()),只需使用return T()
  • 您的ostream&amp; operator&lt;&lt; 不会返回os
  • C++ 不是 java。正如其他人指出的那样,这就像一艘有纱门的船一样泄漏。

标签: c++ operator-overloading


【解决方案1】:

直接的问题是

ostream& operator<< (ostream& os, fraction& frac)

不会接受临时的,因为 frac 不是 const 引用 - 将其更改为

ostream& operator<< (ostream& os, const fraction& frac)

两个分数之间的operator+ 将返回一个无法绑定到非const 引用的临时值。

在这些情况下还有一个非常严重的内存泄漏

fraction operator+ (fraction )
{
   return *(new fraction(this->n*op.d + op.n*this->d, this->d*op.d)); 
}

new 将返回一个动态分配的对象,然后您将其复制并从函数中返回。

像大多数人一样去做:

fraction operator+ (const fraction& op) const
{
   return fraction(this->n*op.d + op.n*this->d, this->d*op.d); 
}

(注意两个额外的常量和引用传递)

【讨论】:

  • 这是最直接的问题,但您可能还应该指出operator+ 等人。应该是 const,并且通常的约定将通过引用 const 传递所有 fraction 争论(即使它可能与此类没有区别)。
  • 你可能应该提到他的流操作员没有返回任何东西。
  • 至于“就像大多数人一样”:我不知道有谁让operator+ 成为会员。大多数时候,您只是从ArithmeticOperators&lt;fraction&gt; 之类的东西继承而来,然后免费获得它。如果没有,它通常是一个在其实现中使用+= 的免费函数。 (当然,你的版本也很好,对于这么简单的课程,也许更可取。)
  • 我让它成为会员,因为我不知道有什么不同。我从来没有使用过一种语言,它可以为你提供这么多方法来做同样的事情,而且大多数时候大多数时候都是错误的。
  • @NeilKirk 没有比您之前评论中的最后一句话更真实的话,除了按照定义,“错误”的东西不是一种方式做某事。 C++ 并不容易。但是,如果您真正为自己付出努力,那么这里有大量的人会帮助您。回报是值得的,所以坚持下去。
猜你喜欢
  • 1970-01-01
  • 2010-10-18
  • 1970-01-01
  • 2013-09-26
  • 1970-01-01
  • 2012-07-30
  • 2019-09-05
  • 1970-01-01
  • 2016-12-13
相关资源
最近更新 更多