Problem with overloading operators.

Let me start this by saying that I don't really understand the concept of overloading operators. I was out sick that day (figures, the one day I miss it's something I can't figure out on my own), and the chapter in the textbook just confused me more.

Having said that, I'm having trouble overloading operators. I honestly haven't the slightest what I've done.

The error I'm getting is from line 15 (and 31, 47, 61, 75 87, 108 and 130), and is along the lines of "operator+ (Rational, Rational) must take either zero or one argument". I'm sure this means that my function call should only include one reference to Rational (such as in line 10 of rational.cpp), but that function only returns an output. How the hell am I supposed to do a function that only calculates a sum if I only use one number to do it?

Anyway, I'm sure I'm missing something fundamental here. But if someone could explain it to me...slowly...in small words...it would be much appreciated.

Thanks! You guys always save my butt!

Jade

prog5.cpp (not finished, but shouldn't be holding anything up from compiling)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include "rational.h"
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>

using namespace std;

int num1, num2;
int den1, den2;
Rational f1, f2;
bool repeat = 0;
char repeatOption;

int main()
{
    while (repeat = 1)
    {
        cout << endl << "Please enter your first fraction's numerator:";
        cin >> num1;
        cout << endl << "Please enter your first fraction's denominator:";
        cin >> den1;
        cout << endl << "Please enter your second fraction's numerator:";
        cin >> num2;
        cout << endl << "Please enter your second fraction's denominator:";
        cin >> den2;

        f1.setNumerator(num1);
        f1.setDenominator(den1);
        f2.setNumerator(num2);
        f2.setDenominator(den2);

        cout << "Output fractions:" << endl << endl;


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

        cout << "Add two fractions:" << endl << endl;

        cout << f1 << " + " << f2 << " = " << f1 + f2;

        cout << "Subtract two fractions:" << endl << endl;

        cout << f1 << " - " << f2 << " = " << f1 - f2;

        cout << "Multiply two fractions:" << endl << endl;

        cout << f1 << " * " << f2 << " = " << f1 * f2;

        cout << "Difide two fractions: " << endl << endl;

        cout << f1 << " / " << f2 << " = " << f1 / f2;

        cout << "Repeat program? Enter 'y' to continue or any other key to exit: ";

        cin >>

         repeatOption;

        if (repeatOption == 'y')
        {
            repeat = 1;
        }

        else
        {
            repeat = 0;
        }
    }



}


rational.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152

#include "rational.h"
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>

using namespace std;


Rational Rational::operator << (Rational r)
{
    cout << r.getNumerator() << "/" << r.getDenominator();
}

Rational Rational::operator + (Rational r1, Rational r2)
{
    int nm1, nm2, nmsum;
    int dn;
    Rational sum;

    dn = r1.getDenominator() * r2.getDenominator();
    nm1 = dn * r1.getNumerator();
    nm2 = dn * r2.getNumerator();
    sum.reduce(nmsum, dn);
    sum.setDenominator(dn);
    nmsum = nm1 + nm2;
    sum.setNumerator(nmsum);
    return sum;
}

Rational Rational::operator - (Rational r1, Rational r2)
{
    int nm1, nm2, nmdiff;
    int dn;
    Rational diff;

    dn = r1.getDenominator() * r2.getDenominator();
    nm1 = dn * r1.getNumerator();
    nm2 = dn * r2.getNumerator();
    diff.reduce(nmdiff, dn);
    diff.setDenominator(dn);
    nmsum = nm1 - nm2;
    diff.setNumerator(nmdiff);
    return diff;
}

Rational Rational::operator * (Rational r1, Rational r2)
{
    int nm;
    int dn;
    Rational prod;

    dn = r1.getDenominator() * r2.getDenominator();
    nm = r2.getNumerator() * r2.getNumerator();
    prod.reduce(nm, dn);
    prod.setNumerator(nm);
    prod.setDenominator(dn);

    return prod;
}

Rational Rational::operator / (Rational r1, Rational r2)
{
    int nm;
    int dn;
    Rational quot;

    nm = r1.getNumerator() * r2.getDenominator();
    dn = r2.getNumerator() * r1.getDenominator();
    quot.reduce(nm, dn);
    quot.setNumerator(nm);
    quot.setDenominator(dn);
    return quot;
}

Rational Rational::operator = (Rational r1, Rational r2)
{
    int nmTemp;
    int dnTemp;

    nmTemp1 = r1.getNumerator();
    dnTemp1 = r1.getDenominator();
    r2.setNumerator(nmTemp1);
    r2.setDenominator(dnTemp1);
    return r2;
}

bool Rational::operator < (Rational r1, Rational r2, bool compare)
{
    int nm1, nm2;
    int dn;

    dn = r1.getDenominator() * r2.getDenominator();
    nm1 = r1.getNumerator() * dn;
    nm2 = r2.getNumerator() * dn;

    if (nm1 < nm2)
    {
        compare = 1;
    }

    else
    {
        compare = 0;
    }
    return compare;
}

bool Rational::operator > (Rational r1, Rational r2, bool compare)
{
    int nm1, nm2;
    int dn;


    dn = r1.getDenominator() * r2.getDenominator();
    nm1 = r1.getNumerator() * dn;
    nm2 = r2.getNumerator() * dn;

    if (nm1 > nm2)
    {
        compare = 1;
    }

    else
    {
        compare = 0;
    }

    return compare;
}

bool Rational::operator == (Rational r1, Rational r2, bool compare)
{
    int nm1, nm2;
    int dn;

    dn = r1.getDenominator() * r2.getDenominaror();
    nm1 = r1.getNumerator() * dn;
    nm2 = r2.getNumerator() * dn;

    if (nm1 == nm2)
    {
        compare = 1;
    }
    else
    {
        compare = 0;
    }

    return compare;
}



rational.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#ifndef RATIONAL_H
#define RATIONAL_H

#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>

using namespace std;

class Rational
{
    friend ostream&operator << (ostream&, Rational);
    private:
        int numerator;
        int denominator;

    public:
        Rational operator << (Rational);
        Rational operator + (Rational);
        Rational operator - (Rational);
        Rational operator * (Rational);
        Rational operator / (Rational);
        Rational operator = (Rational);
        bool operator < (Rational);
        bool operator > (Rational);
        bool operator == (Rational);
        Rational (int, int);
        Rational ();
        int getNumerator();
        int getDenominator();
        void setNumerator(int);
        void setDenominator(int);
        void reduce (int, int);

};

Rational::Rational(int numerator, int denominator)
{}

Rational::Rational() : numerator(1), denominator(1)
{}

int Rational::getNumerator()
{
    return numerator;
}

int Rational::getDenominator()
{
    return denominator;
}

void Rational::setNumerator(int num)
{
    numerator = num;
}

void Rational::setDenominator(int den)
{
    if (den == 0)
    {
        cout << "Zero is not a legal denominator. Setting to 1 instead.";
        denominator = 1;
    }
    else
    {
    denominator = den;
    }

}

void Rational::reduce(int numer, int denom)
{
    int min;
    if (numer < denom)
    {
        min = numer;
    }

    else
    {
        min = denom;
    }

    int n = min;

    for (int count = n; count > 1; count--)
    {
        if(numer % n == 0 && denom % n == 0)
        {
            numer /= n;
            denom /=n;
        }
    }

}

#endif 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Rational Rational::operator + (Rational r1, Rational r2)
{
    int nm1, nm2, nmsum;
    int dn;
    Rational sum;

    dn = r1.getDenominator() * r2.getDenominator();
    nm1 = dn * r1.getNumerator();
    nm2 = dn * r2.getNumerator();
    sum.reduce(nmsum, dn);
    sum.setDenominator(dn);
    nmsum = nm1 + nm2;
    sum.setNumerator(nmsum);
    return sum;
}


In this case, you're definine operator+ as a member of rational, you already have one implicit argment (this.)

If it weren't implicit the prototype would resemble:
Rational Rational::operator + (Rational* this, Rational r1, Rational r2)

And obviously, you don't want operator+ working on 3 objects.

So binary operators, when they're members of a class, should have one (explicit) argument:

Rational Rational::operator + (Rational rhs) const
Last edited on
Fantastic! That actually cleared up quite a bit of confusion for me. I got those errors fixed, but now I'm getting a whole horde of new ones....

I'm posting rational.cpp below....rational.h and prog5.cpp are unchanged from above.

The errors i'm getting are:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/tmp/ccoIMFwp.o: In function `Rational::Rational(int, int)':
rational.cpp:(.text+0x0): multiple definition of `Rational::Rational(int, int)'
/tmp/ccMOqY4e.o:prog5.cpp:(.text+0x0): first defined here
/tmp/ccoIMFwp.o: In function `Rational::Rational(int, int)':
rational.cpp:(.text+0x6): multiple definition of `Rational::Rational(int, int)'
/tmp/ccMOqY4e.o:prog5.cpp:(.text+0x6): first defined here
/tmp/ccoIMFwp.o: In function `Rational::Rational()':
rational.cpp:(.text+0xc): multiple definition of `Rational::Rational()'
/tmp/ccMOqY4e.o:prog5.cpp:(.text+0xc): first defined here
/tmp/ccoIMFwp.o: In function `Rational::Rational()':
rational.cpp:(.text+0x24): multiple definition of `Rational::Rational()'
/tmp/ccMOqY4e.o:prog5.cpp:(.text+0x24): first defined here
/tmp/ccoIMFwp.o: In function `Rational::getNumerator()':
rational.cpp:(.text+0x3c): multiple definition of `Rational::getNumerator()'
/tmp/ccMOqY4e.o:prog5.cpp:(.text+0x3c): first defined here
/tmp/ccoIMFwp.o: In function `Rational::getDenominator()':
rational.cpp:(.text+0x46): multiple definition of `Rational::getDenominator()'
/tmp/ccMOqY4e.o:prog5.cpp:(.text+0x46): first defined here
/tmp/ccoIMFwp.o: In function `Rational::setNumerator(int)':
rational.cpp:(.text+0x52): multiple definition of `Rational::setNumerator(int)'
/tmp/ccMOqY4e.o:prog5.cpp:(.text+0x52): first defined here
/tmp/ccoIMFwp.o: In function `Rational::reduce(int, int)':
rational.cpp:(.text+0x60): multiple definition of `Rational::reduce(int, int)'
/tmp/ccMOqY4e.o:prog5.cpp:(.text+0x60): first defined here
/tmp/ccoIMFwp.o: In function `Rational::setDenominator(int)':
rational.cpp:(.text+0x212): multiple definition of `Rational::setDenominator(int)'
/tmp/ccMOqY4e.o:prog5.cpp:(.text+0xe0): first defined here
/tmp/ccMOqY4e.o: In function `main':
prog5.cpp:(.text+0x324): undefined reference to `operator<<(std::basic_ostream<char, std::char_traits<char> >&, Rational)'
prog5.cpp:(.text+0x351): undefined reference to `operator<<(std::basic_ostream<char, std::char_traits<char> >&, Rational)'
prog5.cpp:(.text+0x3cd): undefined reference to `operator<<(std::basic_ostream<char, std::char_traits<char> >&, Rational)'
prog5.cpp:(.text+0x3fa): undefined reference to `operator<<(std::basic_ostream<char, std::char_traits<char> >&, Rational)'
prog5.cpp:(.text+0x422): undefined reference to `operator<<(std::basic_ostream<char, std::char_traits<char> >&, Rational)'
/tmp/ccMOqY4e.o:prog5.cpp:(.text+0x49e): more undefined references to `operator<<(std::basic_ostream<char, std::char_traits<char> >&, Rational)' follow
collect2: ld returned 1 exit status 


and here's the new rational.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include "rational.h"
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>

using namespace std;


Rational Rational::operator << (Rational r)
{
    cout << r.getNumerator() << "/" << r.getDenominator();
}

Rational Rational::operator + (Rational r)
{
    int nm1, nm2, nmsum;
    int dn;
    Rational sum;


    dn = getDenominator() * r.getDenominator();
    nm1 = dn * getNumerator();
    nm2 = dn * r.getNumerator();
    sum.reduce(nmsum, dn);
    sum.setDenominator(dn);
    nmsum = nm1 + nm2;
    sum.setNumerator(nmsum);
    return sum;
}

Rational Rational::operator - (Rational r)
{
    int nm1, nm2, nmdiff;
    int dn;
    Rational diff;

    dn = getDenominator() * r.getDenominator();
    nm1 = dn * getNumerator();
    nm2 = dn * r.getNumerator();
    diff.reduce(nmdiff, dn);
    diff.setDenominator(dn);
    nmdiff = nm1 - nm2;
    diff.setNumerator(nmdiff);
    return diff;
}

Rational Rational::operator * (Rational r)
{
    int nm;
    int dn;
    Rational prod;

    dn = getDenominator() * r.getDenominator();
    nm = getNumerator() * r.getNumerator();
    prod.reduce(nm, dn);
    prod.setNumerator(nm);
    prod.setDenominator(dn);
    return prod;
}

Rational Rational::operator / (Rational r)
{
    int nm;
    int dn;
    Rational quot;

    nm = getNumerator() * r.getDenominator();
    dn = r.getNumerator() * getDenominator();
    quot.reduce(nm, dn);
    quot.setNumerator(nm);
    quot.setDenominator(dn);
    return quot;
}

Rational Rational::operator = (Rational r)
{
    int nmTemp;
    int dnTemp;

    nmTemp = getNumerator();
    dnTemp = getDenominator();
    r.setNumerator(nmTemp);
    r.setDenominator(dnTemp);
    return r;
}

bool Rational::operator < (Rational r)
{
    int nm1, nm2;
    int dn;
    bool compare;

    dn = getDenominator() * r.getDenominator();
    nm1 = getNumerator() * dn;
    nm2 = r.getNumerator() * dn;

    if (nm1 < nm2)
    {
        compare = 1;
    }

    else
    {
        compare = 0;
    }
    return compare;
}

bool Rational::operator > (Rational r)
{
    int nm1, nm2;
    int dn;
    bool compare;

    dn = getDenominator() * r.getDenominator();
    nm1 = getNumerator() * dn;
    nm2 = r.getNumerator() * dn;

    if (nm1 > nm2)
    {
        compare = 1;
    }

    else
    {
        compare = 0;
    }

    return compare;
}

bool Rational::operator == (Rational r)
{
    int nm1, nm2;
    int dn;
    bool compare;

    dn = getDenominator() * r.getDenominator();
    nm1 = getNumerator() * dn;
    nm2 = r.getNumerator() * dn;

    if (nm1 == nm2)
    {
        compare = 1;
    }
    else
    {
        compare = 0;
    }

    return compare;
}


any idea what might be causing these errors?

Thank you again, cire, SO MUCH!!!!

Jade
Well, it seems to think you have implemented some member functions of Rational twice. Once in prog5.cpp and once in Rational.cpp. I suspect you did something like the following in Rational.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
class Rational
{
public:
     // ...

    Rational( int, int) ;
};


Rational::Rational(int n, int d)
{
     //definition here
}



If you do that, the definition of the function must be declared inline:

1
2
3
4
inline Rational::Rational(int n, int d)
{
     // definition here.
}



The last set of errors has to do with:
1
2
3
4
Rational Rational::operator << (Rational r)
{
    cout << r.getNumerator() << "/" << r.getDenominator();
}

not being enough to make

cout << R ;

work, where R is a Rational object.


What you want is a non-member function:

1
2
3
4
ostream& operator<<(ostream & os, Rational r)
{
    return os << r.GetNumerator() << '/' << r.getDenominator() ;
}


Either as an inline function in Rational.h or with a declaration in Rational.h and definition in Rational.cpp.
Last edited on
I looked through rational.h and didn't see anything that was like that really. The only things I saw were the default constructor and the constructor, but that didn't seem like it would do that.

Could it have something to do with the #ifndef? I read something about having to use that when you include a file twice (from two different files), and I've got it in mine....but maybe I did it wrong?

Thanks!
Jade
Topic archived. No new replies allowed.