Przeciążanie operatorów liczby zespolone i sprzężenie zespolone

0

Mam spory problem. Nie rozumiem czemu nam każą zdefiniować tyle operatorów. Ten program ma wczytywać i wypisywać liczby zespolone i robić na nich jakieś działania. Co do tych operatorów to nam kazał przeczytać to: https://stackoverflow.com/questions/7578682/why-should-i-overload-a-c-operator-as-a-global-function-stl-does-and-what-ar and

  1. Muszę zrobić 5 operatorów jako funkcje składowe klasy, które przyjmują jeden argument: +, −, !, ++, −−.

  2. Muszę zrobić 5 operatorów jako funkcje składowe klasy, które przyjmują dwaargumenty: =,+=, −=, *=, /=; Then

  3. Muszę zrobić 8 operatorów jako globalne funkcje zaprzyjaźnione +, −, *, /, ==, !=, <<, >> które przyjmują dwa parametry. Zrobiłem je jako tako

    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;
    }

A tu co mam zrobić, chyba to ma zwracać wartość bool no nie?

    friend const Comp operator==(const Comp& x, const Comp& y)
    {

    }
    friend const Comp operator!=(const Comp& x, const Comp& y)
    {

    }

No i nie wiem co mam wstawić w operatorach tych 1) 2). 1) przyjmuje tylko jeden argument, więc co mam tam napisać wewnątrz tej funkcji, że dodaje ten pierwszy argument z pierwszym argumentem czy co?. 2) Np. += - o co w tym chodzi dla mnie to bez sensu. To chyba po prostu będzie to samo co dodawnie w tych globalnych funkcjach zaprzyjaźnionych?

    Comp operator+(const Comp& x);
    Comp operator-(const Comp& x);
    bool operator!(void);
    const Comp& operator++();
    const Comp operator++(int);
    const Comp& operator--();
    const Comp operator--(int);
    Comp operator=(const Comp x);
    Comp operator-=(const Comp& x);
    Comp operator+=(const Comp& x);
    Comp operator*=(const Comp& x);
    Comp operator/=(const Comp& x);

Wyskoczył mi error, gdy nic tam do środka nie dawałem

/tmp/ccAWMNiS.o: In function `main':
complex.cpp:(.text+0x516): undefined reference to `Comp::operator+(Comp const&)'
complex.cpp:(.text+0x536): undefined reference to `Comp::operator=(Comp)'
complex.cpp:(.text+0x5b2): undefined reference to `Comp::operator-(Comp const&)'
complex.cpp:(.text+0x5d2): undefined reference to `Comp::operator=(Comp)'
complex.cpp:(.text+0x66e): undefined reference to `Comp::operator=(Comp)'
complex.cpp:(.text+0x70a): undefined reference to `Comp::operator=(Comp)'
collect2: error: ld returned 1 exit status

Mam też problem z obliczaniem sprzężenia. Jak mogę to policzyć, próbowałem tak, ale mi wychodzi 0,0 zamiast np. rzecz i -urojona

    const Comp conj(void) const
    {
        Comp temp;
        -im();
        return temp;
    }

Oto mój cały kod. Później go rozbiję na osobny plik h, osobny plik z klasą i osbny tam gdzie main.

#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;
    imag;
    }
    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;
        -im();
        return temp;
    }
    ~Comp(){}
    /*
    Comp operator+(const Comp& x);
    Comp operator-(const Comp& x);
    bool operator!(void);
    const Comp& operator++();
    const Comp operator++(int);
    const Comp& operator--();
    const Comp operator--(int);
    Comp operator=(const Comp x);
    Comp operator-=(const Comp& x);
    Comp operator+=(const Comp& x);
    Comp operator*=(const Comp& x);
    Comp operator/=(const Comp& x);
    */
    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 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 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;
}  

2

Self insercik na temat: https://dsp.krzaq.cc/post/304/jak-przeladowywac-operatory-w-mojej-klasie/ Powinien rozwiać wątpliwości, szczególnie że opiera się na implementacji podobnej klasy

No i nie wiem co mam wstawić w operatorach tych 1) 2). 1) przyjmuje tylko jeden argument, więc co mam tam napisać wewnątrz tej funkcji, że dodaje ten pierwszy argument z pierwszym argumentem czy co?

Użyj this

  1. Np. += - o co w tym chodzi dla mnie to bez sensu. To chyba po prostu będzie to samo co dodawnie w tych globalnych funkcjach zaprzyjaźnionych?

Chyba źle rozumiesz

int a = 5;
int b = 10;
a += b; // operator +=
// a == 15
    const Comp conj(void) const
    {
        Comp temp;
        -im();
        return temp;
    }

Const na wartości zwracanej nie ma sensu (ale też nie jest istotą błędu). Problem jest taki, że zwracasz temp, któremu nic nie przypisałeś.

int a;
sin(0);
return a;
// co zostało zwrócone i jak bardzo wywołanie jakiejś funkcji nie ma wpływu na `a`?
2

W dokumentacji jest dobry artykuł:
https://en.cppreference.com/w/cpp/language/operators

2

++ i -- w liczbach ciągłych, np zespolonych, nie ma sensu

0

Napisałem ten program, mam nadzieję, że wyszedł dobrze. Co sądzicie. JA go jeszcze rozpisze, żeby w osobnym pliku było main, osobno .h i osobno klasa, wiecie co mam na myśli pewnie.

#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)
    {
        return *this;
    }
    Comp& operator-=(const Comp& x)
    {
        return *this;
    } 
    Comp operator+=(const Comp& x)
    {
        return *this;
    }
    Comp operator*=(const Comp& x)
    {
        return *this;
    }
    Comp operator/=(const Comp& x)
    {
        return *this;
    } 
    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;
}  

3
    Comp& operator-=(const Comp& x)
    {
        return *this;
    } 
    Comp operator+=(const Comp& x)
    {
        return *this;
    }
    Comp operator*=(const Comp& x)
    {
        return *this;
    }
    Comp operator/=(const Comp& x)
    {
        return *this;
    } 

nope nope nope

    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;
    }

Zaimplementuj je w oparciu o wersje @=

4

Kilka uwag:

  1. Nie musisz używać słowa void w sygnaturze funkcji które nie przyjmują żadnych parametrów.
  2. W większości funkcji zwracany typ obiekty jest stały tzn const Comp, co ogranicza wywołanie funkcji do tych, które nie modyfikują stanu klasy. Stąd też wywołanie ++(a+b) nie będzie możliwe.
  3. Pusty niewirtualny destruktor nie musi być jawnie zdefiniowany.
  4. W konstruktorze użyj listy inicjalizacyjnej do ustawienia wartości zmiennych.
  5. Funkcja operator/ nie jest zabezpieczona przed dzieleniem przez zero.
  6. W funkcjach operator== i operator!= porównujesz ze sobą liczby zmiennoprzecinkowe, co w niektórych przypadkach może dać błędny wynik. zobacz. Dlatego też w poniższym przykładzie.
    Comp a { 0.1*0.1 , 0.1*0.1 } , b { 0.01 , 0.01 };
    Comp c { 0.01 , 0.01 };

    if( a == b ) std::cout << "Equal a and b" << std::endl;
    if( c == b ) std::cout << "Equal c and b" << std::endl;

a nie będzie równe b.

3
    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;
    }

Coś mi mówi, że nie tak się mnoży i dzieli liczby zespolone. W szczególności, (2-i)/(1-i) != 2+i, tylko 1.5 + 0.5i.

0

Zrobiłem to w wersji

class X
{
 public:
  X& operator+=(const X& rhs) // compound assignment (does not need to be a member,
  {                           // but often is, to modify the private members)
    /* addition of rhs to *this takes place here */
    return *this; // return the result by reference
  }
 
  // friends defined inside class body are inline and are hidden from non-ADL lookup
  friend X operator+(X lhs,        // passing lhs by value helps optimize chained a+b+c
                     const X& rhs) // otherwise, both parameters may be const references
  {
    lhs += rhs; // reuse compound assignment
    return lhs; // return the result by value (uses move constructor)
  }
};

Napisałem kod

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

Wyskakują mi błędy

complex.cpp:91:45: error: ‘ComplexNumbers::Comp ComplexNumbers::Comp::operator-=(int, const ComplexNumbers::Comp&)’ must take exactly one argument
     Comp operator-=(int value, const Comp& x)
                                             ^
complex.cpp:97:45: error: ‘ComplexNumbers::Comp ComplexNumbers::Comp::operator+=(int, const ComplexNumbers::Comp&)’ must take exactly one argument
     Comp operator+=(int value, const Comp& x)
                                             ^
complex.cpp:103:45: error: ‘ComplexNumbers::Comp ComplexNumbers::Comp::operator*=(int, const ComplexNumbers::Comp&)’ must take exactly one argument
     Comp operator*=(int value, const Comp& x)
                                             ^
complex.cpp:109:45: error: ‘ComplexNumbers::Comp ComplexNumbers::Comp::operator/=(int, const ComplexNumbers::Comp&)’ must take exactly one argument
     Comp operator/=(int value, const Comp& x)

2

I jak myślisz, co te błędy mogą oznaczać?

0

Powinienem użyć jednego argumentu. Ale nie rozumiem tego. W działaniu += mam jakąś liczbę zespoloną jak pierwszy argument i co teraz robię? Znowu dodaje tą liczbę zespoloną do siebie? Czyli liczba zespolona zapisana w pliku to: (1.7,3.14), czyli mój operator będzie dodawała jedną i tą samą liczbę zespoloną czy co on ma w sumie zrobić, wynik takiego += ma być (3.4,6.28)???? Czy może ten operator dodaje jakąś liczbę zupełnie z kosmosu typu jakąś int value i wtedy próbowałem to zrobić tak, ale nie wychodzi, bo pisze mi undefined reference czy coś takiego

    Comp operator-=(const Comp& x)
    {
        int value = 0;
        value -= x.real;
        value -= x.imag;
        return *this;
    } 

Wtedy mi wyskakuje taki błąd

/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
/tmp/ccOxwzXe.o: In function `ComplexNumbers::main(int, char**)':
complex.cpp:(.text+0x49): undefined reference to `std::basic_ifstream<char, std::char_traits<char> >::basic_ifstream(char const*, std::_Ios_Openmode)'
complex.cpp:(.text+0x5e): undefined reference to `std::basic_ios<char, std::char_traits<char> >::operator!() const'
complex.cpp:(.text+0x70): undefined reference to `std::cerr'
complex.cpp:(.text+0x75): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)'
complex.cpp:(.text+0x91): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)'
complex.cpp:(.text+0x9b): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)'
complex.cpp:(.text+0xa6): undefined reference to `std::ostream::operator<<(std::ostream& (*)(std::ostream&))'
complex.cpp:(.text+0xe1): undefined reference to `std::basic_ofstream<char, std::char_traits<char> >::basic_ofstream(char const*, std::_Ios_Openmode)'
complex.cpp:(.text+0xf6): undefined reference to `std::basic_ios<char, std::char_traits<char> >::operator!() const'
complex.cpp:(.text+0x108): undefined reference to `std::cerr'
complex.cpp:(.text+0x10d): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)'
complex.cpp:(.text+0x129): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)'
complex.cpp:(.text+0x133): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)'
complex.cpp:(.text+0x13e): undefined reference to `std::ostream::operator<<(std::ostream& (*)(std::ostream&))'
complex.cpp:(.text+0x162): undefined reference to `std::basic_ios<char, std::char_traits<char> >::clear(std::_Ios_Iostate)'
complex.cpp:(.text+0x196): undefined reference to `std::istream::seekg(std::fpos<__mbstate_t>)'
complex.cpp:(.text+0x1e8): undefined reference to `std::cout'
complex.cpp:(.text+0x23f): undefined reference to `std::cout'
complex.cpp:(.text+0x25a): undefined reference to `std::cout'
complex.cpp:(.text+0x25f): undefined reference to `std::ostream::operator<<(double)'
complex.cpp:(.text+0x269): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)'
complex.cpp:(.text+0x274): undefined reference to `std::ostream::operator<<(std::ostream& (*)(std::ostream&))'
itp.

Ja znalazłem to opisane tutaj

class X
{
 public:
  X& operator+=(const X& rhs) // compound assignment (does not need to be a member,
  {                           // but often is, to modify the private members)
    /* addition of rhs to *this takes place here */
    return *this; // return the result by reference
  }
 
  // friends defined inside class body are inline and are hidden from non-ADL lookup
  friend X operator+(X lhs,        // passing lhs by value helps optimize chained a+b+c
                     const X& rhs) // otherwise, both parameters may be const references
  {
    lhs += rhs; // reuse compound assignment
    return lhs; // return the result by value (uses move constructor)
  }
};

Tylko, że w friends można dawać dwa argumenty, a już wewnątrz jako funkcje składową nie.
Już mogli napisać jak to się robi, a napisali tylko komentarz /* addition of rhs to *this takes place here */ - no i skąd wiadomo co tam wpisać????

 X& operator+=(const X& rhs) // compound assignment (does not need to be a member,
  {                           // but often is, to modify the private members)
    /* addition of rhs to *this takes place here */
    return *this; // return the result by reference
  }
0

Błędy linkera dotyczą czegoś innego. Nie pisz z góry kodu który się nie kompiluje, tylko pisz małymi krokami w taki sposób, żeby kod cały czas się kompilował. W takim wypadku będziesz wiedział, że to to co dodałeś jest błędne, a nie reszta kodu.

Swoją drogą:

class Comp
{
    Comp operator-=(int value, const Comp& x);
};
class X
{
    X& operator+=(const X& rhs)
};

Znajdź różnice. Typ zwracany jest ważny, nie chcesz robić kopii. Dałem wcześniej linka, który zawiera pełne przykłady. Spojrzałeś chociaż?

    Comp operator-=(const Comp& x)
    {
        int value = 0;
        value -= x.real;
        value -= x.imag;
        return *this;
    } 

To jako całość nie ma sensu. Gdy piszesz a += b to wywołujesz a.operator+=(b). Dodaj te wartości do obecnej liczby zespolonej.

Może to to jest problemem.

struct foo
{
    int x;
    int x_times_two();
};

// ...

foo f = {21};
cout << f.x_times_two();

jak myślisz, skąd funkcja x_times_two wie które x pomnożyć?

0

Naprawiłem to wszystko, ale nadal są błędy kompilatora to undefined reference

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

Na tamto co wkleiłeś patrzyłem i to było mega dziwne

fraction& operator*=(fraction const& o) {
    num *= o.num;
    den *= o.den;
    int div = experimental::gcd(num, den);
    num /= div;
    den /= div;
    return *this;
}

Nie wiem dlaczego ty tam później dzielisz, przecież to jest mnożenie no nie?
Ja to spróbowałem zrobić tak, to miałem znów błędy to z undefined reference

 Comp& operator*=(const Comp& x)
    {
        real *= x.real;
        imag *= x.imag;
        return *this;
    }
0

Te błędy "undefined reference" są do zupełnie innych rzeczy (wystarczy przeczytać). Wygląda jakbyś próbował kompilować za pomocą gcc albo clang zamiast g++ albo clang++

Ostatni operator *= jest ok, tylko jest logicznie niepoprawny dla mnożenia liczb zespolonych. Dla mnożenia ułamków dzielę przez wspólny dzielnik co skutkuje uproszczeniem ułamka (2/3 * 1/4 to 2/12, ale sensowniej 1/6).

0

Nareszcie się udało. Porgram daje dobre wyniki i jest już prawie na ukończeniu. Jedynym problemem jest, że jak dam w komentarz ten operator

/*
    Comp& operator=(const Comp x)
    {
        return *this;
    }*/

to daje normalne wyniki

(1.10,2.00) 
(1.70,3.14) 
2.28
3.57
1.07
1.07
(1.10,-2.00) 
(1.70,-3.14) 
(2.80,5.14) 
(-0.60,-1.14) 
(-4.41,6.85) 
(0.64,-0.00)

Ale jak włącze go normalnie do kodu, to daje same zera

(1.10,2.00) 
(1.70,3.14) 
2.28
3.57
1.07
1.07
(1.10,-2.00) 
(1.70,-3.14) 
(0.00,0.00) 
(0.00,0.00) 
(0.00,0.00) 
(0.00,0.00) 

Ciekawe dlaczego????

Tutaj cały kod

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

namespace ComplexNumbers
{
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(){}
    const Comp operator+();
    const Comp operator-();
    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)
    {
        return *this;
    }
    Comp& operator-=(const Comp& x)
    {
        int value = 0;
        value -= x.real;
        value -= x.imag;
        return *this;
    } 
    Comp& operator+=(const Comp& x)
    {
        int value = 0;
        value += x.real;
        value += x.imag;
        return *this;
    }
    Comp& operator*=(const Comp& x)
    {
        int value = 0;
        value *= x.real;
        value *= x.imag;
        return *this;
    }
    Comp& operator/=(const Comp& x)
    {
        int value = 0;
        value /= x.real;
        value /= x.imag;
        return *this;
    } 
    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 - x.imag * y.imag);
        temp.imag = (x.real * y.imag + x.imag * y.real);
        return temp;
    }
    friend const Comp operator/(const Comp& x, const Comp& y)
    {
        Comp temp;
        temp.real = ((x.real * y.real) + (x.imag * y.imag))/(y.real*y.real + y.imag*y.imag);
        temp.imag = ((x.imag * y.real) - (x.real * y.imag))/(y.real*y.real + y.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 = '0';
        return wart2>>c>>b.real>>c>>b.imag>>c; 
    }
};
}
using namespace ComplexNumbers;
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;
}  

1

Na pewno daje dobre wyniki? Dlaczego nie masz konstruktora pozwalającego nadać wartości? Twój operator= nic nie robi, powinien przypisywać.

2

Jedynym problemem jest, że jak dam w komentarz ten operator .... to daje normalne wyniki

W takim przypadku kompilator tworzy domyślny operator przypisania, który w odróżnieniu od Twojej implementacji jest poprawnie zdefiniowany.
Nie widzę potrzeby aby w tym przypadku tworzyć własną implementację operatora przypisania.

3

Ten operator nie ma najmniejszego sensu:

    Comp& operator+=(const Comp& x)
    {
        int value = 0;
        value += x.real;
        value += x.imag;
        return *this;
    }

To tak jakby napisać

    Comp& operator+=(const Comp& x)
    {
        int marchewka = 0;
        marchewka += x.real;
        marchewka += x.imag;
        return *this;
    }

Zupełnie pomijając fakt, że zostawisz tę marchewkę na zgnicie w nieużywanej ramce funkcji.

1 użytkowników online, w tym zalogowanych: 0, gości: 1