0

I have a problem. I create a program, which works on complex numbers, but I have a problem with overloading operators. My teacher said that I must create a lot of them, he said that I should check this link Why should I overload a C++ operator as a global function (STL does) and what are the caveats? 1) I must create 5 operators which are member function of class and which have one argument: +, −, !, ++, −−. Then

2) I must create 5 operators which are member function of class and which two arguments: =,+=, −=, *=, /=; Then

3) I must create 8 operators which are global friend function +, −, *, /, ==, !=, <<, >> and take two parameters.

My teacher said that I must change the declaration of these operators 2) and think about what they will do? Do you know how to change them?

    Comp operator=(const Comp x) = default;
    Comp operator-=(const Comp& x, int value)
    {
        x.real -= value;
        x.imag -= value;
        return x;
    } 
    Comp operator+=(const Comp& x, const Comp& y)
    {
        x.real += y.real;
        x.imag += y.imag;
        return x;
    }
    Comp operator*=(const Comp& x, const Comp& y)
    {
        x.real *= y.real;
        x.imag *= y.imag;
        return x;
    }
    Comp operator/=(const Comp& x, const Comp& y)
    {
        x.real /= y.real;
        x.imag /= y.imag;
        return x;
    } 

I get a lot of errors:

complex.cpp:74:45: error: ‘Comp Comp::operator-=(const Comp&, int)’ must take exactly one argument
     Comp operator-=(const Comp& x, int value)
                                             ^
complex.cpp:80:49: error: ‘Comp Comp::operator+=(const Comp&, const Comp&)’ must take exactly one argument
     Comp operator+=(const Comp& x, const Comp& y)
                                                 ^
complex.cpp:86:49: error: ‘Comp Comp::operator*=(const Comp&, const Comp&)’ must take exactly one argument
     Comp operator*=(const Comp& x, const Comp& y)
                                                 ^
complex.cpp:92:49: error: ‘Comp Comp::operator/=(const Comp&, const Comp&)’ must take exactly one argument
     Comp operator/=(const Comp& x, const Comp& y)
                                                 ^
complex.cpp:73:10: error: defaulted declaration ‘Comp Comp::operator=(Comp)’
     Comp operator=(const Comp x) = default;
          ^~~~~~~~
complex.cpp:73:10: error: does not match expected signature ‘constexpr Comp& Comp::operator=(Comp&)’

I also want to know is these operator are ok?

    Comp operator+(const Comp& x);
    Comp operator-(const Comp& x);
    bool operator!(void);
    const Comp& operator++()
    { 
        return *this;
    }
    const Comp operator++(int)
    { 
        Comp temp(*this); 
        operator++(); 
        return temp;  
    }
    const Comp& operator--()
    {
        return *this;
    }
    const Comp operator--(int)
    {
        Comp temp(*this); 
        operator--(); 
        return temp; 
    } 

This is my whole code

#include <fstream>
#include <cstdlib> 
#include <iostream>
#include <iomanip>
#include <cmath>
#ifndef M_PI
    #define M_PI 3.14159265358979323846
#endif
using namespace std;


class Comp {
    double real, imag;

public:
    Comp(){
    real=0;
    imag=0;
    }
    double re(void) const
    {
        return real;
    }
    double im(void) const
    {
        return imag;
    }
    double mod(void) const
    {
        return sqrt(re()*re() + im()*im());
    }
    double arg(void) const
    {
        double faza;
        if (im() >= 0)
            faza = acos(re()/mod());
        else
            faza = 2*M_PI - acos(re()/mod());

    return faza;
    }
    const Comp conj(void) const
    {
        Comp temp;
        temp.real = re();
        temp.imag = -im();
        return temp;
    }
    ~Comp(){}
    Comp operator+(const Comp& x);
    Comp operator-(const Comp& x);
    bool operator!(void);
    const Comp& operator++()
    { 
        return *this;
    }
    const Comp operator++(int)
    { 
        Comp temp(*this); 
        operator++(); 
        return temp;  
    }
    const Comp& operator--()
    {
        return *this;
    }
    const Comp operator--(int)
    {
        Comp temp(*this); 
        operator--(); 
        return temp; 
    } 
    Comp operator=(const Comp x) = default;
    Comp operator-=(const Comp& x, int value)
    {
        x.real -= value;
        x.imag -= value;
        return x;
    } 
    Comp operator+=(const Comp& x, const Comp& y)
    {
        x.real += y.real;
        x.imag += y.imag;
        return x;
    }
    Comp operator*=(const Comp& x, const Comp& y)
    {
        x.real *= y.real;
        x.imag *= y.imag;
        return x;
    }
    Comp operator/=(const Comp& x, const Comp& y)
    {
        x.real /= y.real;
        x.imag /= y.imag;
        return x;
    } 
    Comp operator=(const Comp x, const Comp y);
    Comp operator-=(const Comp& x, const Comp& y);
    Comp operator+=(const Comp& x, const Comp& y);
    Comp operator*=(const Comp& x, const Comp& y);
    Comp operator/=(const Comp& x, const Comp& y);

    friend const Comp operator+(const Comp& x, const Comp& y)
    {
        Comp temp;
        temp.real = x.real + y.real;
        temp.imag = x.imag + y.imag;
        return temp;
    }
    friend const Comp operator-(const Comp& x, const Comp& y)
    {
        Comp temp;
        temp.real = x.real - y.real;
        temp.imag = x.imag - y.imag;
        return temp;
    }
    friend const Comp operator*(const Comp& x, const Comp& y)
    {
        Comp temp;
        temp.real = x.real * y.real;
        temp.imag = x.imag * y.imag;
        return temp;
    }
    friend const Comp operator/(const Comp& x, const Comp& y)
    {
        Comp temp;
        temp.real = x.real / y.real;
        temp.imag = x.imag / y.imag;
        return temp;
    }
    friend bool operator==(const Comp& x, const Comp& y)
    {
        if (x.real == y.real && x.imag == y.imag)
            return 1;
        else
            return 0;
    }
    friend bool operator!=(const Comp& x, const Comp& y)
    {

        if (x.real != y.real || x.imag != y.imag)
            return 1;
        else
            return 0;
    }

    friend std::ostream& operator<<(std::ostream& wart1,  const Comp& a)
    {
        return wart1 <<fixed << setprecision(2) << '(' << a.re() << "," << a.im() << ')' << ' ' << endl;
    }
    friend std::istream& operator>>(std::istream& wart2, Comp& b){
        char c;
        return wart2>>c>>b.real>>c>>b.imag>>c; 
    }
};

int main(int argc, char* argv[])
{ 
    ifstream read(argv[1]);
    if (!read)
        { cerr << "Open error: " << argv[1] << endl; exit(1);}
    ofstream write(argv[2]);

    if(!write) { cerr << "Open error: " << argv[2] << endl; exit(2);} 
    read.clear();
    read.seekg(0);
    Comp x1;
    read >> x1;
    write << x1;
    cout << x1;
    Comp x2;
    read >> x2;
    write << x2;
    cout << x2;
    cout << x1.mod() << endl;
    cout << x2.mod() << endl;
    cout << x1.arg() << endl;
    cout << x2.arg() << endl;
    cout << x1.conj();
    cout << x2.conj();
    write << x2;
    write << x1.mod() << endl;
    write << x2.mod() << endl;
    write << x1.arg() << endl;
    write << x2.arg() << endl;
    write << x1.conj();
    write << x2.conj();
    Comp sum;
    sum = x1 + x2;
    cout << sum;
    write << sum;
    Comp sub;
    sub = x1 - x2;
    cout << sub;
    write << sub;
    Comp mult;
    mult = x1 * x2;
    cout << mult;
    write << mult;
    Comp div;
    div = x1 / x2;
    cout << div;
    write << div;

    return 0;
}  
Adam
  • 2,820
  • 1
  • 13
  • 33
Jakub
  • 679
  • 5
  • 16
  • 2
    The error output is actually pointing to the exact problem: **complex.cpp:74:45: error: ‘Comp Comp::operator-=(const Comp&, int)’ must take exactly one argument Comp operator-=(const Comp& x, int value)**. `operator-=` needs one argument, not two. Maybe read up on operator overloading: https://en.cppreference.com/w/cpp/language/operators. There is an example with operator=* for Fraction at the bottom which should be useful. – Mikael H Jun 15 '20 at 11:56
  • 1
    Also read: [What are the basic rules and idioms for operator overloading?](https://stackoverflow.com/questions/4421706/what-are-the-basic-rules-and-idioms-for-operator-overloading) – Yksisarvinen Jun 15 '20 at 11:58
  • 1
    Unrelated, but if `Comp` stands for complex your * operator does not follow the rules for complex arithmetics... – Serge Ballesta Jun 15 '20 at 12:04
  • A good, higher level rule is to test your code more often as you write it. You wrote an operator that didn't compile -- and then you wrote *four more.* So either you didn't test that first one before proceeding, or you did test it, got the error, and kept on writing bad code without understanding what had gone wrong. Either way, much of that effort was wasted and is now causing more confusion. **Never add to code that doesn't work.** – Beta Jun 15 '20 at 12:10
  • 1
    make sure `const` is used correctly – user6386155 Jun 15 '20 at 12:19

2 Answers2

1

Operator overloading is no different from other functions' overloading, so you must not change the function signature, but only its implementation. If that's a task for your university subject then go ahead and implement all the operators, otherwise you don't need to provide a custom version of all the operators for any class you build, but only when you really need them.

Hack06
  • 963
  • 1
  • 12
  • 20
1

You got the signature right for

Comp operator+(const Comp& x);
Comp operator-(const Comp& x);

but not for

Comp operator-=(const Comp& x, int value)

...and others.

When implemented as member functions, operators always operate on this. Ie your operator-= would be called as

Comp a,b;
a.operator-=(b,42);

but you want

a.operator-=(42);
463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185