Przeładowanie operatorow >>, <<, +

Przeładowanie operatorow >>, <<, +
MI
  • Rejestracja:prawie 11 lat
  • Ostatnio:około 5 lat
  • Postów:243
0
Kopiuj
#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.

twonek
  • Rejestracja:prawie 11 lat
  • Ostatnio:prawie 2 lata
  • Postów:2500
2

http://ideone.com/Typ99k

  1. Zwracasz referencję do lokalnej zmiennej:
Kopiuj
complex & operator+ (complex & liczba1,complex & liczba2)
{
    complex sum;
    ....
    return sum;
}
  1. Próbujesz przekazać tymczasową zmienną jako referencję:
Kopiuj
ostream & operator<< (ostream & screen, complex & liczba)
...
cout << a+b;
  1. Nie wyrzucasz niepotrzebnych śmieci ze strumienia podczas wczytania.
_13th_Dragon
ostream &amp; operator&lt;&lt; (ostream &amp; screen, complex &amp; liczba) - czyli const complex X(1); nie chcesz umieć wyświetlić.
MI
  • Rejestracja:prawie 11 lat
  • Ostatnio:około 5 lat
  • Postów:243
0
Kopiuj
#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ł?

edytowany 1x, ostatnio: Mikilll
twonek
popatrz jeszcze raz uważnie na link w moim poście
twonek
poza tym po co wklejasz jeszcze raz stary niepoprawny kod?
MI
Punkty 1 i 2 zrealizowałem z twojej wypowiedzi. Co do 3 to nie wiem za bardzo jak. A tak poza tym sory za kod. Pomyliłem się przy wklejaniu. Teraz masz tutaj działający kod.
twonek
Popatrz na mój link, tam masz poprawiony punkt 3. Nawet z przykładem działania.
twonek
I źle naprawiłeś punkt 2. Popatrz na mój kod.
MI
  • Rejestracja:prawie 11 lat
  • Ostatnio:około 5 lat
  • Postów:243
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ść.

twonek
Nie przekazuj przez wartość jeśli możesz przez const &amp;. Unikniesz niepotrzebnego kopiowania plus innych pułapek typu object slicing.
MI
A wytłumaczyłbyś dlaczego kompilator nie godzi się na przekazanie niestałej wartości przez referencję? Bo nie za bardzo to rozumiem.
twonek
Bo obiekt tymczasowy może w każdej chwili zniknąć, więc odwołanie się do niego jest jak spanie w budynku przeznaczonym do rozbiórki. const &amp; wydłuża życie takiego obiektu do zakończenia życia tej referencji. Dlaczego więc normalna referencja nie wydłuża życia? Bo przy normalnej referencji możesz również modyfikować taki obiekt, a raczej nie chcemy modyfikować czegoś co zaraz zniknie. Operacja bezsensowna, a może wprowadzać błędy trudne do zauważenia.
_13th_Dragon
  • Rejestracja:prawie 20 lat
  • Ostatnio:9 dni
1

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

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

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
edytowany 2x, ostatnio: _13th_Dragon
MI
Dzięki. Oczywiście masz rację że w moim programie jest jeszcze sporo niedopracowań jak np. ujemna część urojona etc, ale i tak dzięki za rady.
MI
Niestety jednak twój program nie obsługuje strumienia wejścia w taki sposób jaki ja chciałem. A chciałem żeby to użytkownik podawał przez cin wyrażenie np. 2+6j, a nie jak u ciebie 2 6.
_13th_Dragon
To zrób tak jak chciałeś, powiedziałem że nie jest dobrym podejściem mazanie po ekranie podczas wczytywania.
MI
  • Rejestracja:prawie 11 lat
  • Ostatnio:około 5 lat
  • Postów:243
0
Kopiuj
#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ć?

_13th_Dragon
  • Rejestracja:prawie 20 lat
  • Ostatnio:9 dni
1

to zamień na:

Kopiuj
cout<<a<<endl<<'+'<<endl<<b<<endl<<'='<<endl<<(a+b)<<endl;

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
Zobacz pozostałe 3 komentarze
_13th_Dragon
Jak zamienisz tym co podałem to co masz to zobaczysz czemu ci nie działa.
MI
No fajnie, że mi to pokazałeś że mój program w ogóle nie widzi znaku części urojonej. Masz pomysł co zrobić żeby program wczytywał część urojoną razem ze znakiem?
_13th_Dragon
Tak, a nawet go podałem.
MI
Jeżeli masz na myśli ten kod co wstawiłeś powyżej to on też "zjada" minus przed częścią urojoną.
MI
  • Rejestracja:prawie 11 lat
  • Ostatnio:około 5 lat
  • Postów:243
0
Kopiuj
#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?

_13th_Dragon
  • Rejestracja:prawie 20 lat
  • Ostatnio:9 dni
1

To:

Kopiuj
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:

Kopiuj
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();


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
Zobacz pozostałe 4 komentarze
MI
Ja chcę w jednej linii 2+3j, a nie, że część rzeczywista w jednym wierszu, a część urojona w drugim.
_13th_Dragon
Ja to zrozumiałem, pokazałem jak to zrobić, wytłumaczyłem jak działa twój kod (w tym poście). Więc powiedz o co jeszcze pytasz?
MI
To może wrzuć prawidłowo wg ciebie napisany kod i zobaczymy czy to działa czy nie, bo chyba nie rozumiesz o co mi chodzi. Napisałem że chcę, aby użytkownik wprowadzał w taki oto sposób liczbę zespoloną przez cin: 2+3j, 8+6j etc.
MI
Ten twój kod się nie kompiluje. Poza tym jest w nim to samo co u mnie, tylko trochę inaczej zapisane.
MI
  • Rejestracja:prawie 11 lat
  • Ostatnio:około 5 lat
  • Postów:243
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.

edytowany 1x, ostatnio: Mikilll
_13th_Dragon
  • Rejestracja:prawie 20 lat
  • Ostatnio:9 dni
1

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

Kopiuj
   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:

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

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


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
MI
Dzięki. Nie myślałem, że to takie proste. Wcześniej niepotrzebnie kombinowałem z cin.ignore().
_13th_Dragon
Chrzani waść, z ignore() też zadziała (oczywiście na końcu).

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.