制作"cout << obj1 + obj2 << endl;" 工作

pet*_*kun 0 c++ operator-overloading

所以,我已经为obj1 + obj2进行了类内运算符重载:

fraction operator+ (fraction op);
Run Code Online (Sandbox Code Playgroud)

类似地,cout << obj正在通过重载运算符重载ostream来工作:

ostream& operator<< (ostream& os, fraction& frac);
Run Code Online (Sandbox Code Playgroud)

但是,如果我试图将两者结合起来,那么一切都会破裂.

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)’
Run Code Online (Sandbox Code Playgroud)

这是代码:

#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;
}
Run Code Online (Sandbox Code Playgroud)

救命.d:

Luc*_*ore 9

当前的问题是

ostream& operator<< (ostream& os, fraction& frac)
Run Code Online (Sandbox Code Playgroud)

不会接受临时因为frac不是const参考 - 将其更改为

ostream& operator<< (ostream& os, const fraction& frac)
Run Code Online (Sandbox Code Playgroud)

operator+两个分数之间将返回一个临时的,不能绑定到非const引用.

在这些情况下,还存在非常严重的内存泄漏:

fraction operator+ (fraction )
{
   return *(new fraction(this->n*op.d + op.n*this->d, this->d*op.d)); 
}
Run Code Online (Sandbox Code Playgroud)

new 将返回一个动态分配的对象,然后从该函数复制并返回该对象.

就像大多数人一样:

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

(注意两个额外的consts和参考传递)

  • 这是当前的问题,但你也应该指出`operator +`等.应该是const,并且通常的约定会通过引用const传递所有的"fraction"参数(尽管它可能与这个类没有区别). (3认同)
  • 至于"就像大多数人一样":我不知道有谁使`operator +`成为会员.大多数时候,你只是继承了像`ArithmeticOperators <fraction>`这样的东西,并免费获得它.如果没有,它通常是一个在其实现中使用`+ =`的自由函数.(但是,当然,你的版本也很完美,对于一个这么简单的类,可能更好.) (3认同)