Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

klasa do obsługi liczb zespolonych a przeładowanie operatorów

Ostatnio zmodyfikowano 2016-09-02 19:35
Autor Wiadomość
monterinio
Temat założony przez niniejszego użytkownika
klasa do obsługi liczb zespolonych a przeładowanie operatorów
» 2016-09-02 14:34:03
Dla sportu piszę sobie klasę do obsługi liczb zespolonych, ale natrafiłem na problem.
C/C++
//przeladowany operator +
Zesp operator +( Zesp z ) {
    Zesp roboczy;
    roboczy.re =( * this ).re + z.re;
    roboczy.im =( * this ).im + z.im;
    return roboczy;
}

// przeladowany operator =+
Zesp & operator +=( Zesp z ) {
    ( * this ) =( * this ) + z;
    return( * this );
}

// przeladowany operator <<
ostream & operator <<( ostream & wypis, Zesp & z ) {
    wypis << z.re << " + " << z.im << "i";
    return wypis;
}
Problem jest taki:
C/C++
cout << z1 + z2;
Powyższe wyrażenie nie jest możliwe, dlatego że funkcja operator+ zwraca przez wartość, a funkcja operator<< & odbiera przez referencję. Jak to obejść, żeby było tak samo dobrze jak dla typów wbudowanych?
P-151321
karambaHZP
» 2016-09-02 14:59:06
Przeładowany
operator <<
 powinien być friend z klasą
Zesp
.
P-151324
mateczek
» 2016-09-02 15:00:46
dał być cały kod było by łatwiej przerobić !!! jeśli chcesz przez referencję to referencja do r-value przejdzie :)

C/C++
#include <iostream>
using namespace std;
class Zesp {
    int re;
    int im;
    friend ostream & operator <<( ostream & wypis, Zesp && z );
public:
    Zesp( int _re, int _im )
        : re( _re )
         , im( _im )
    {
       
    }
    Zesp operator +( Zesp z ) {
        Zesp roboczy( 0, 0 );
        roboczy.re =( * this ).re + z.re;
        roboczy.im =( * this ).im + z.im;
        return roboczy;
    }
   
    // przeladowany operator =+
    Zesp & operator +=( Zesp z ) {
        ( * this ) =( * this ) + z;
        return( * this );
    }
   
    // przeladowany operator <<
   
};

ostream & operator <<( ostream & wypis, Zesp && z ) {
    wypis << z.re << " + " << z.im << "i";
    return wypis;
}

int main() {
    Zesp z1( 2, 2 );
    Zesp z2( 4, 5 );
    cout << z1 + z2 << endl;
}
P-151325
monterinio
Temat założony przez niniejszego użytkownika
» 2016-09-02 15:06:16
C/C++
#include <iostream>
using namespace std;
/////////////////////////////////////////////////////////////////////
class Zesp {
    double re;
    double im;
public:
    // deklaracja przyjaźni z funkcją operator <<
    friend ostream & operator <<( ostream & ekran, Zesp & z );
   
    // konstruktor (domniemany, bo bez argumentow)
    Zesp( double x = 0, double y = 0 )
        : re( x )
         , im( y )
    { /*pusty konstrktor*/ }
   
    //przeladowany operator +
    Zesp operator +( Zesp z ) {
        Zesp roboczy;
        roboczy.re =( * this ).re + z.re;
        roboczy.im =( * this ).im + z.im;
        return roboczy;
    }
   
    // przeladowany operator =+
    Zesp & operator +=( Zesp z ) {
        ( * this ) =( * this ) + z;
        return( * this );
    }
   
   
};
// przeladowany operator <<
ostream & operator <<( ostream & wypis, Zesp & z ) {
    wypis << z.re << " + " << z.im << "i";
    return wypis;
}
/////////////////////////////////////////////////////////////////////
int main() {
    Zesp z1( 3, 4 );
    Zesp z2( 4, 3 );
    Zesp z3( 1, 5 );
    z3 = z1 + z2;
    operator <<( cout, z1 );
}
To cały kod. W twoim kodzie w przeładowanym operatorze << jest podwójna referencja do z (?). Mógłbyś mi to przybliżyć?

EDIT: próbuję skompilować twój kod na Ubuntu 14, środowisko Eclipse, Cross GCC i dostaję błąd przy deklaracji przyjaźni i przy definicji przeładowanego operatora:
"expected ',' or '...' before '&&' token
P-151326
Gibas11
» 2016-09-02 15:47:25
Masz włączony standard c++11? (opcja -std=c++11) I dlaczego Cross GCC a nie zwykłe GCC? :O
P-151330
michal11
» 2016-09-02 16:16:45
Operator + i += powinny być ze sobą sparowane, mniej więcej na takiej zasadzie:
C/C++
class Test
{
private:
   
    int a, b;
   
public:
   
    Test()
        : a( 1 )
         , b( 100 )
    { }
   
    Test & operator +=( const Test & t )
    {
        a += t.a;
        b += t.b;
       
        return * this;
    }
   
    Test operator +( const Test & t )
    {
        Test ret( * this );
       
        ret += t;
       
        return ret;
    }
};

inna sprawa, że moim zdaniem operator + nie powinien być skladową klasy (i chyba operator += też ale tego nie jestem pewnien).

P-151332
monterinio
Temat założony przez niniejszego użytkownika
» 2016-09-02 16:32:16
michal11 - a możesz uzasadnić dlaczego powinny być w ten sposób sparowane? I dlaczego funkcję powinienem dać poza klasą? W końcu sam jestem jej autorem i mam do niej pełny dostęp. Czy są jakieś inne powody?
Gibas11 - c++11 ustawione zgodnie z jakimś tutorialem na stackoverflow. na drugą część pytania nie potrafie odpowiedzieć. ;)
P-151333
Gibas11
» 2016-09-02 16:43:23
@up
a możesz uzasadnić dlaczego powinny być w ten sposób sparowane?
Jeśli zmienisz klasę będzie wystarczyło poprawić tylko jedną metodę, poza tym zasada DRY. :)

c++11 ustawione zgodnie z jakimś tutorialem na stackoverflow. na drugą część pytania nie potrafie odpowiedzieć.
To trochę dziwne, u mnie GCC na Linuksie radzi sobie z kompilacją. Cross GCC służy do kompilowania na inne platformy, zwykłe gcc (bez cross) kompiluje z zamiarem uruchomienia na tym samym systemie i architekturze procesora.
Co wypisuje polecenie
gcc --version
?
P-151334
« 1 » 2
  Strona 1 z 2 Następna strona