Like Tree2Danke
  • 1 Beitrag von deepthroat
  • 1 Beitrag von Matthias Reitinger
ERLEDIGT
NEIN
ANTWORTEN
13
ZUGRIFFE
1684
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
  1. #1
    Reyme ist offline Mitglied
    Registriert seit
    Feb 2012
    Beiträge
    14
    Hallo
    Ich hab mal wieder ein Problem:
    Da in meinem "C++-Programmierer" gerade das Überladen von Operatoren durchgenommen wird, dachte ich mir, ich programmiere eine kleine Klasse für rationale Zahlen. Hier ein kleiner Codeausschnitt:

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    //rational.h
     
    #ifndef RATIONAL_H
    #define RATIONAL_H
     
    class rational {
           [...]
    }
     
    [...]
     
    rational operator+ (rational& r1, rational& r2);
    std::ostream& operator<< (std::ostream& os, rational& r);
     
    #endif //RATIONAL_H

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    //rational.cpp
     
    #include "rational.h"
     
    rational operator+ (rational& r1, rational& r2) {
         [...]
    }
     
    std::ostream& operator<< (ostream& os, rational& r) {
        return os << r.getzaehler() << " / " << r.getnenner();
    }

    Das Überladen des +-Operators funktioniert, aber beim compilieren des <<-Operators erhalte ich die Fehlermeldung
    Fehler: "ofstream" im Namensbereich "std" bezeichnet keinen Typ


    PS: Wenn das etwas helfen sollte: Ich arbeite mit Code::Blocks

    Wäre schön wenn jemand eine Antwort für mich hätte

    Oh ich habe mich verschrieben

    bei rational.cpp das "return" weglassen
     
    Ich hab keinen Plan :D

  2. #2
    Avatar von sheel
    sheel ist offline Moderator
    tutorials.de Moderator
    Registriert seit
    Jul 2007
    Beiträge
    6.727
    Hi

    da gehört aber ein return.

    In welcher Zeile wird er Fehler gezeigt?
    ostream ist dreinmal mit std:: und einmal ohne.
     
    Netiquette (vA §15) und Nutzungsregeln (vA §4.8) einhalten! Programmcode in Codetags/Codeboxen.
    Sehr gute Beiträge bitte Bewerten (Stern darunter oder "Danke").
    "Funktioniert nicht" ist zu ungenau! Code, Fehlermeldungen, Verhalten des Programms, ...?

  3. #3
    Reyme ist offline Mitglied
    Registriert seit
    Feb 2012
    Beiträge
    14
    Das std hab ich jetzt noch ergänzt, die Fehlermeldung bleibt aber

    Die Fehlermeldung bezieht sich auf Z. 13 von rational.h
     
    Ich hab keinen Plan :D

  4. #4
    Avatar von sheel
    sheel ist offline Moderator
    tutorials.de Moderator
    Registriert seit
    Jul 2007
    Beiträge
    6.727
    Da Teile rausgenommen sind: Was ist bei dir Zeile 13?
    Komplette Datei wäre sowieso hilfreich.
     
    Netiquette (vA §15) und Nutzungsregeln (vA §4.8) einhalten! Programmcode in Codetags/Codeboxen.
    Sehr gute Beiträge bitte Bewerten (Stern darunter oder "Danke").
    "Funktioniert nicht" ist zu ungenau! Code, Fehlermeldungen, Verhalten des Programms, ...?

  5. #5
    Avatar von Endurion
    Endurion ist offline Mitglied Diamant
    Registriert seit
    Apr 2004
    Beiträge
    2.216
    Die Fehlermeldung sagt ofstream, überall sonst schreibst du aber ostream. Ist da ein f reingerutscht?
     

  6. #6
    Reyme ist offline Mitglied
    Registriert seit
    Feb 2012
    Beiträge
    14
    Nein, da ist mir bei der Fehlermeldung ein f reingerutscht

    Z. 13 bezieht sich auf den Code oben

    Hier aber mal der komplette Code(weil er gewünscht ist):

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    
    //rational.h
     
    #ifndef RATIONAL_H
    #define RATIONAL_H
     
    class rational {
        public:
            rational(int z, int n);
            rational(rational& r);
     
            void setzaehler(int z);
            void setnenner(int n);
     
            const int getzaehler();
            const int getnenner();
     
            const double getwert();
     
            bool operator>= (rational& r);
            bool operator<= (rational& r);
            bool operator<  (rational& r);
            bool operator>  (rational& r);
            bool operator== (rational& r);
     
            rational& operator= (rational& r);
        private:
            int zaehler;
            int nenner;
    };
     
    inline rational::rational(int z = 0, int n = 0)
        : zaehler(z), nenner(n) {};
     
    inline rational::rational(rational& r)
        : zaehler(r.zaehler), nenner(r.nenner) {};
     
    inline void rational::setzaehler(int z) {
        zaehler = z;
    }
     
    inline void rational::setnenner(int n) {
        nenner = n;
    }
     
    inline const int rational::getnenner() {
        return nenner;
    }
     
    inline const int rational::getzaehler() {
        return zaehler;
    }
     
    inline const double rational::getwert() {
        return static_cast<double> (zaehler) / static_cast<double>(nenner);
    }
     
    rational operator+ (rational& r1, rational& r2);
    std::ostream& operator<< (std::ostream& os, rational& r);
     
    #endif //RATIONAL_H

    und

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    
    //rational.cpp
     
    #include "rational.h"
     
    rational operator+ (rational& r1, rational& r2) {
        rational temp(0, 0);
        temp.setzaehler(r1.getzaehler() * r2.getnenner() + r2.getzaehler() * r1.getnenner());
        temp.setnenner(r1.getnenner() * r2.getnenner());
     
        return temp;
    }
     
    inline bool rational::operator>=(rational& r) {
        return getwert() >= r.getwert();
    }
     
    inline bool rational::operator<=(rational& r) {
        return getwert() <= r.getwert();
    }
     
    inline bool rational::operator< (rational& r) {
        return getwert() < r.getwert();
    }
     
    inline bool rational::operator> (rational& r) {
        return getwert() > r.getwert();
    }
     
    inline bool rational::operator== (rational& r) {
        return getwert() == r.getwert();
    }
     
    rational& rational::operator= (rational& r) {
        zaehler = r.getzaehler();
        nenner = r.getnenner();
     
        return *this;
    }
     
    std::ostream& operator<< (std::ostream& os, rational& r) {
        return os << r.getzaehler() << '/' << r.getnenner();
    }

    Jetzt bezieht sich die Fehlermeldung auf Z. 58 der "rational.h" Datei
     
    Ich hab keinen Plan :D

  7. #7
    deepthroat ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jun 2005
    Beiträge
    8.731
    Hi.

    Wenn du std::ostream in einer Datei verwenden willst, mußt du natürlich auch die entsprechende Headerdatei einbinden welche diesen Typ deklariert. Da ist die Fehlermeldung doch eigentlich hinreichend deutlich...

    Übrigens ist "const" als Modifzierer bei Rückgabetypen unsinnig. Die get Methoden solltest du stattdessen als const markieren:
    Code cpp:
    1
    2
    3
    4
    5
    
    // nicht so:
    const /* <-- hat keine Wirkung */ double getwert();
     
    // sondern so:
    double getwert() const;
    Gruß
    Reyme bedankt sich. 
    If at first you don't succeed, try again. Then quit. No use being a damn fool about it.

  8. #8
    Registriert seit
    Dec 2001
    Ort
    Bayern
    Beiträge
    5.785
    Hallo,

    du hast vergessen, in rational.h den Header <ostream> einzubinden:

    Code cpp:
    1
    
    #include <ostream>

    Grüße,
    Matthias

    \edit: Zu langsam…

    Um doch noch was Neues beizutragen: an allen Stellen in deinem Code, an denen du eine Referenz als Argument übergibst, kannst du genauso gut auch eine Const-Referenz übergeben. Du modifizierst die übergebenen Instanzen schließlich nicht. Ansonsten kannst du z.B. kein const rational addieren oder ausgeben.
    Geändert von Matthias Reitinger (07.04.12 um 22:50 Uhr)
    Reyme bedankt sich. 
    „Gib einem Menschen einen Fisch, und er wird für einen Tag satt. Lehre ihn Fischen, und er wird ein Leben lang satt.“
    “For every complex problem, there is an answer that is short, simple and wrong.”
    “Pessimism is safe, but optimism is a lot faster!”

  9. #9
    Reyme ist offline Mitglied
    Registriert seit
    Feb 2012
    Beiträge
    14
    Vielen Dank für die Hilfe
     
    Ich hab keinen Plan :D

  10. #10
    Reyme ist offline Mitglied
    Registriert seit
    Feb 2012
    Beiträge
    14
    Aber wenn wir schonmal dabei sind über überladene Operatoren zu reden:

    Gibt es eigentlich eine feste Regel, wann man die Übergabe per Referenz oder per Wert verwendet oder muss man sich in jedem einzelnen Fall Gedanken dazu machen?
     
    Ich hab keinen Plan :D

  11. #11
    ibafluss ist offline Mitglied Gold
    Registriert seit
    Feb 2011
    Beiträge
    240
    Gedanken solltest du dir beim Programmieren immer machen
    Aber beim Überladen von Operatoren kannst du die Variablen eigentlich immer per Referenz übergeben.
    Anders ist es beim Zurückgeben: Bei operator+() zum Beispiel musst du ein neues Objekt zurückgeben (du kannst in die übergebenen Parameter ja nicht das Ergebnis der Addition speichern). Also bei der Rückgabe solltest du die schon überlegen, was besser ist, bei der Übergabe eigentlich immer Referenz.

    Lg
     

  12. #12
    Reyme ist offline Mitglied
    Registriert seit
    Feb 2012
    Beiträge
    14
    Was ich dabei aber ein bisschen ärgerlich finde:

    ich kann bei dem Beispiel oben z.B nicht schreiben
    Code :
    1
    2
    3
    4
    5
    6
    7
    
     
    int main() {
         rational r1(2, 5);
         rational r2(3, 5);
         
         rational r3(r1 + r2);
    }

    , da der Konstruktor eine Referenz erwartet, bei der Addition aber ein Wert zurückgegeben wird . Ist aber insgesamt gesehen nicht schlimm, da man auch
    Code :
    1
    2
    
    rational r3;
    r3 = r1 + r2;
    schreiben kann.

    Oder gibt es da noch eine andere Möglichkeit, mit der man das umgehen kann?
     
    Ich hab keinen Plan :D

  13. #13
    Avatar von sheel
    sheel ist offline Moderator
    tutorials.de Moderator
    Registriert seit
    Jul 2007
    Beiträge
    6.727
    Das angesprochene Poblem ist auf die (älteren) Versionen vom Standart zurückzuführen,
    die keine R-Value-Referenzen erlauben/ermöglichen

    (L-Value/R-Value: Was bei einer Zuweisung (ohne Op-Überladung) links und rechts stehen kann.
    x=y
    x kann eine Variable sein
    y kann eine Variable oder ein Wert sein
    Du übergibst einen Wert, Referenzen gehen aber nur auf dem Compiler benannte Variablen)

    Das sollte inzwischen (aufgrund dem neuen C++-Standart ab gcc 4.3) unerstützt werden.
    Mal testen...

    edit: Also bei mir gehts mit den Rvalues wie erwartet.
     
    Netiquette (vA §15) und Nutzungsregeln (vA §4.8) einhalten! Programmcode in Codetags/Codeboxen.
    Sehr gute Beiträge bitte Bewerten (Stern darunter oder "Danke").
    "Funktioniert nicht" ist zu ungenau! Code, Fehlermeldungen, Verhalten des Programms, ...?

  14. #14
    deepthroat ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jun 2005
    Beiträge
    8.731
    Zitat Zitat von Reyme Beitrag anzeigen
    Was ich dabei aber ein bisschen ärgerlich finde:

    ich kann bei dem Beispiel oben z.B nicht schreiben
    Code :
    1
    2
    3
    4
    5
    6
    7
    
     
    int main() {
         rational r1(2, 5);
         rational r2(3, 5);
         
         rational r3(r1 + r2);
    }

    , da der Konstruktor eine Referenz erwartet,
    Du sprichst vom Kopierkonstruktor. Dieser sollte immer eine konstante Referenz übergeben bekommen, das funktioniert dann nämlich auch mit temporären Objekten (also mit deinem Beispiel).

    Code cpp:
    1
    2
    3
    4
    5
    6
    7
    8
    
    class rational {
    ...
    public:
      rational(const rational& other);
    };
     
    ...
    rational c(a + b); // OK
    Zitat Zitat von Reyme Beitrag anzeigen
    . bei der Addition aber ein Wert zurückgegeben wird . Ist aber insgesamt gesehen nicht schlimm, da man auch
    Code :
    1
    2
    
    rational r3;
    r3 = r1 + r2;
    schreiben kann.
    Das ist natürlich nicht wirklich optimal und bei deinem Code auch gar nicht möglich, da du keinen Standardkonstruktor definiert hast.

    Gruß
     
    If at first you don't succeed, try again. Then quit. No use being a damn fool about it.

Thema nicht erledigt

Ähnliche Themen

  1. Überladen von Operatoren
    Von LukeS im Forum C/C++
    Antworten: 2
    Letzter Beitrag: 24.07.08, 23:04
  2. Überladen in C++
    Von fox_2_k im Forum C/C++
    Antworten: 4
    Letzter Beitrag: 15.06.08, 01:31
  3. Antworten: 9
    Letzter Beitrag: 29.05.05, 23:03
  4. Axis Problem beim Methoden überladen
    Von cham im Forum Java
    Antworten: 1
    Letzter Beitrag: 25.01.05, 18:13
  5. Antworten: 5
    Letzter Beitrag: 09.09.02, 16:33

Stichworte