Przeładowanie operatorow >>, <<, +

0
#include <iostream>

using namespace std;

class complex
{
private:
    double re,im;

public:
    complex(double real=0,double imaginary=0) : re(real),im(imaginary){}
    friend ostream & operator<< (ostream & screen,complex & liczba);
    friend istream & operator>> (istream & keyboard,complex & liczba);
    friend complex & operator+ (complex & liczba1,complex & liczba2);
};

ostream & operator<< (ostream & screen,complex & liczba)
{
    screen << liczba.re << "+" << liczba.im << "j";
    return screen;
}

istream & operator>> (istream & keyboard,complex & liczba)
{
    cout << "Re: ";
    keyboard >> liczba.re;
    cout << "Im: ";
    keyboard >> liczba.im;
    return keyboard;
}

complex & operator+ (complex & liczba1,complex & liczba2)
{
    complex sum;
    sum.re=liczba1.re+liczba2.re;
    sum.im=liczba1.im+liczba2.im;
    return sum;
}

int main()
{
    cout << "Podaj a" << endl;
    complex a; cin >> a;
    cout << "Podaj b" << endl;
    complex b; cin >> b;
    cout << a+b;
    return 0;
}

 

Po 1:
Dlaczego część rzeczywistą liczby zespolonej dodaje mi prawidłowo, a przypadku części urojonej wychodzą jakieś głupoty? Jak stworzę np. obiekt c, a następnie wykonam c=a+b to wtedy jest git, ale mnie interesuje czemu nie działa mi taki zapis jak powyżej.

Po 2: Jak już uda się ogarnąć zagadnienie powyżej to chciałbym tak przeładować operator >> aby użytkownik wprowadzał po prostu napis 3+5j i od razu program będzie wiedział, że wprowadziłem dla danego obiektu część rzeczywistą liczba.re=3 i część urojoną liczba.im=5 . Próbowałem sam to zrobić niestety z marnym skutkiem.

2

http://ideone.com/Typ99k

  1. Zwracasz referencję do lokalnej zmiennej:
complex & operator+ (complex & liczba1,complex & liczba2)
{
    complex sum;
    ....
    return sum;
}
  1. Próbujesz przekazać tymczasową zmienną jako referencję:
ostream & operator<< (ostream & screen, complex & liczba)
...
cout << a+b;
  1. Nie wyrzucasz niepotrzebnych śmieci ze strumienia podczas wczytania.
0
#include <iostream>

using namespace std;

class complex
{
private:
    double re,im;

public:
    complex(double real=0,double imaginary=0) : re(real),im(imaginary){}
    friend ostream & operator<< (ostream & screen,complex liczba);
    friend istream & operator>> (istream & keyboard,complex & liczba);
    friend complex operator+ (complex liczba1,complex liczba2);
};

ostream & operator<< (ostream & screen,complex liczba)
{
    screen << liczba.re << "+" << liczba.im << "j";
    return screen;
}

istream & operator>> (istream & keyboard,complex & liczba)
{
    cout << "Re: ";
    keyboard >> liczba.re;
    cout << "Im: ";
    keyboard >> liczba.im;
    return keyboard;
}

complex operator+ (complex liczba1,complex liczba2)
{
    complex sum;
    sum.re=liczba1.re+liczba2.re;
    sum.im=liczba1.im+liczba2.im;
    return sum;
}

int main()
{
    cout << "Podaj a" << endl;
    complex a; cin >> a;
    cout << "Podaj b" << endl;
    complex b; cin >> b;
    cout << a+b;
    return 0;
}


Dzięki za rady. Działa. Dobrze by było teraz przejść do zagadnienia nr 2. Ktoś ma pomysł jak to zrobić? Bo próbowałem czegoś w stylu:

char plus, j;
keyboard >> liczba.re >> plus >> liczba.im >> j;

ale to nie działa. Ktoś ma pomysł?

0

Dzięki twonek. Odnośnie pktu drugiego to można też zamiast pisać const przed liczba można też po prostu przekazywać tę liczbę przez wartość.

1

Czy wiesz że możesz robić to tak:

class complex
  {
   public:
   double re,im; // Nie widzę powodu dla którego to musi być private
   complex(double re=0,double im=0):re(re),im(im) {} // nie widzę powodu parametry nazywac inaczej niż składowe
   friend ostream & operator<< (ostream & screen,const complex &liczba) // ma sens przekazanie stałej referencji
     {
      return screen<<liczba.re<<(liczba.im>=0?"+":"")<<liczba.im<<"j"; // trzeba dać więcej warunków bo głupio wygląda 1+0i
     }
   friend istream & operator>> (istream & keyboard,complex & liczba);
     {
      return keyboard>>liczba.re>>liczba.im; // nie rób tu wyświetleń, bo nie będzie można użyć do wczytania z pliku
     }
  };
0
#include <iostream>

using namespace std;

class complex
{
private:
    double re,im;

public:
    complex(double real=0,double imaginary=0) : re(real),im(imaginary){}
    friend ostream & operator<< (ostream & screen,const complex & liczba);
    friend istream & operator>> (istream & keyboard,complex & liczba);
    friend complex operator+ (complex & liczba1,complex & liczba2);
};

ostream & operator<< (ostream & screen,const complex & liczba)
{
    if(liczba.im>0)
        screen << liczba.re << "+" << liczba.im << "j";
    else if(liczba.im==0)
        screen << liczba.re;
    else
        screen << liczba.re << "-" << liczba.im << "j";
    return screen;
}

istream & operator>> (istream & keyboard,complex & liczba)
{
    keyboard >> liczba.re;
    keyboard.ignore();
    keyboard >> liczba.im;
    keyboard.ignore();
    return keyboard;
}

complex operator+ (complex & liczba1,complex & liczba2)
{
    complex sum;
    sum.re=liczba1.re+liczba2.re;
    sum.im=liczba1.im+liczba2.im;
    return sum;
}

int main()
{
    cout << "Podaj a" << endl;
    complex a; cin >> a;
    cout << "Podaj b" << endl;
    complex b; cin >> b;
    cout << a+b;
    return 0;
}

Spójrz na moją wersję. Nie wiem jak zrobić, aby program poprawnie działał dla ujemnej części urojonej. Program w przypadku ujemnej części urojonej od razu zmienia jej znak na +.

Spróbuj np.

Podaj a:
-3-3j
Podaj b:
-3-2j

Na ekranie wyświetli ci się -3+5j

Ktoś wie jak to naprawić?

1

to zamień na:

cout<<a<<endl<<'+'<<endl<<b<<endl<<'='<<endl<<(a+b)<<endl;
0
#include <iostream>

using namespace std;

class complex
{
private:
    double re,im;

public:
    complex(double real=0,double imaginary=0) : re(real),im(imaginary){}
    friend ostream & operator<< (ostream & screen,const complex & liczba);
    friend istream & operator>> (istream & keyboard,complex & liczba);
    friend complex operator+ (complex & liczba1,complex & liczba2);
};

ostream & operator<< (ostream & screen,const complex & liczba)
{
    if(liczba.im<0)
        screen << liczba.re << liczba.im << "j";
    else
        screen << liczba.re << "+" << liczba.im << "j";
    return screen;
}

istream & operator>> (istream & keyboard,complex & liczba)
{
    keyboard >> liczba.re;
    keyboard.ignore();
    keyboard >> liczba.im;
    keyboard.ignore();
    return keyboard;
}

complex operator+ (complex & liczba1,complex & liczba2)
{
    complex sum;
    sum.re=liczba1.re+liczba2.re;
    sum.im=liczba1.im+liczba2.im;
    return sum;
}

int main()
{
    cout << "Podaj a" << endl;
    complex a; cin >> a;
    cout << "Podaj b" << endl;
    complex b; cin >> b;
    cout<<a<<endl<<'+'<<endl<<b<<endl<<'='<<endl<<(a+b)<<endl;
    return 0;
}

Program działa prawidłowo tylko wtedy gdy liczbę zespoloną wprowadzamy w ten sposób 4 +2j, 3 -2j,8 -7j, czyli ze spacją po części rzeczywistej. Wygląda to jednak nienaturalnie. Czy ktoś wie jak zrobić, aby w programie dało się normalnie wprawadzać liczby zespolone, tzn. 4+2j, 3-2j, 8-7j?

1

To:

istream & operator>> (istream & keyboard,complex & liczba)
{
    keyboard >> liczba.re;
    keyboard.ignore();
    keyboard >> liczba.im;
    keyboard.ignore();
    return keyboard;
}

Będzie działać tylko jeżeli wpiszesz zamiast: 4 +2j
to:

4 a tu dowolny tekst którego może i nie być a część urojona koniecznie w następnym wierszu
+2 tu też dowolny tekst może być samo `j` a może być nic

czemu - poczytaj dokumentacje na ignore();

0

@13th_Dragon Może wklej działający kod, w którym jak użytkownik poda liczbę a np. 2-4j (w ten sposób bez spacji), następnie poda liczbę b 2+2j (też w ten sposób) to otrzyma wynik 4-2j.

BTW: Może to być link z Ideone.

1

To mi powiedz jak mam określić człowieka który z kodu:

   friend istream & operator>>(istream & keyboard,complex & liczba)
     {
      return keyboard>>liczba.re>>liczba.im; // nie rób tu wyświetleń, bo nie będzie można użyć do wczytania z pliku
     }

oraz informacji:

tylko doczytaj jeden znak - ten j

nie jest w stanie wyprodukować to:

   friend istream & operator>>(istream & keyboard,complex & liczba)
     {
      char ch;
      return keyboard>>liczba.re>>liczba.im>>ch;
     }

Powinieneś rozważyć zmianę kierunku na dziennikarstwo.

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