Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to output multiplied user created class c++

I am working on an assignment overloading operators for a user-created class of rational numbers but can not output two "Rational" objects in the same line. For example:

std::cout<<5*10<<std::endl;

Outputs 50 just fine. However when I try to do,

std::cout<<Rational_1*Rational_2<<std::endl;

I receive an error. If I instead assign the value to a third rational such as

Rational_3=Rational_1*Rational_2;
std::cout<<Rational_3<<std::endl;

Then the program outputs just fine. I have brought this up to my professor but even he does not know how to fix it. Any explanation as to why this is happening would be helpful. I would like to know why this is an issue instead of just simply getting a piece of code that works.

#include <iostream>
using namespace std;
class Rational{
    public:
        Rational();
        Rational(int whole_number);
        Rational(int numerator_input,int denominator_input);
        friend Rational operator *(Rational rat_1, Rational rat_2);
    `   friend ostream& operator <<(ostream& out,Rational& output);
        void simplify();
    private:
        int numerator,denominator;
};

int main(){
    Rational r1(2,3),r2(3,4),r3;
    r3=r1*r2;
    cout<<r3<<endl;
    //cout<<r1*r2<<endl;

return 0;
}

Rational::Rational(){
    numerator=0;
    denominator=1;
}

Rational::Rational(int whole_number){
    numerator=whole_number;
    denominator=1;
}

Rational::Rational(int numerator_input,int denominator_input){
    numerator=numerator_input;
    if(denominator_input==0){
        cout<<"A rational number can not have a 0 in the denominator\n";
        exit (5);
    }
    denominator=denominator_input;
    simplify();
}

ostream& operator <<(ostream& out,Rational& output){
    out<<output.numerator<<"/"<<output.denominator; 
    return out;
}

Rational operator *(Rational rat_1, Rational rat_2){
    Rational rat_3;
    rat_1.simplify();
    rat_2.simplify();
    rat_3.numerator=rat_1.numerator*rat_2.numerator;
    rat_3.denominator=rat_1.denominator*rat_2.denominator;
    rat_3.simplify();
    return rat_3;
}

void Rational::simplify(){
    //Flip negative sign to numerator
    for(int counter=1000000;counter>0;counter--){
        if((numerator%counter==0)&&(denominator%counter==0))
        {
            numerator=numerator/counter;
            denominator=denominator/counter;    
        }   
    }   
}
like image 464
Drew Mares Avatar asked Mar 01 '18 17:03

Drew Mares


2 Answers

Declare the operator like

friend ostream& operator <<(ostream& out, const Rational& output);
                                          ^^^^^

You may not bind a temporary object to a non-constant lvalue reference.

like image 32
Vlad from Moscow Avatar answered Nov 16 '22 01:11

Vlad from Moscow


The difference between the operator<< that takes an int as in your first snippet is that it takes it's argument by value.

Your overloaded operator<< takes a Rational object by reference and Rational_1*Rational_2 returns an temporary object, temporary objects are not allowed to bind to non-const references.

Either take your argument by value or by const& to fix this:

friend ostream& operator <<(ostream& out, const Rational& output);

Or

friend ostream& operator <<(ostream& out, Rational output);
like image 198
Hatted Rooster Avatar answered Nov 16 '22 03:11

Hatted Rooster