.. Im Gültigkeitsbereich nicht definiert / OOP Problem



  • Hallo,

    Ich arbeite grade dieses Tutorial durch:
    http://www.highscore.de/cpp/aufbau/klassen.html#klassen_einfuehrung

    Ich bin nun Bei Aufgabe 1 (Währungseingabe).

    Wie der Tip sagt, habe ich die Aufgabe versucht, über ein enum zu lösen, wahrscheinlich ist mir dabei ein Fehler unterlaufen, denn g++ sagt

    In file included from kunde.cpp:2:
    kunde.h:14: Fehler: »Einheit« bezeichnet keinen Typ
    kunde.cpp: In member function »int kunde::waehrung_waehlen()«:
    kunde.cpp:34: Fehler: »waehrung« wurde in diesem Gültigkeitsbereich nicht definiert
    In file included from main.cpp:1:
    kunde.h:14: Fehler: »Einheit« bezeichnet keinen Typ
    

    Hier mal die 2 Dateien:

    // kunde.h
    #include <string>                                                                                                 
    
    class kunde                                                                                                       
        {                                                                                                             
        public:                                                                                                       
            void geldkarte_einschieben();                                                                             
            bool PIN_eingeben();                                                                                      
            bool betrag_waehlen();                                                                                    
            int waehrung_waehlen();                                                                                   
    
        private:                                                                                                      
            std::string Benutzername;                                                                                 
            std::string PIN;                                                                                          
            Einheit waehrung;                                                                                         
        };
    
    //kunde.cpp
    #include "kunde.h"
    #include "bank.h"
    #include <iostream>
    #include <string>
    
    bank b;
    
    void kunde::geldkarte_einschieben()
    {
        std::cout << "Schieben Sie bitte Ihre Karte in den Automat: " << std::flush;
        std::cin >> Benutzername;
    }
    
    bool kunde::PIN_eingeben()
    {
        std::cout << "Geben Sie Ihre PIN ein: " << std::flush;
        std::cin >> PIN;
        return b.zugriff_ueberpruefen (Benutzername, PIN);
    }
    
    bool kunde::betrag_waehlen()
    {
        std::cout << "Geben Sie ein, wieviel Geld Sie abheben moechten: " << std::flush;
        int Betrag;
        std::cin >> Betrag;
        return b.geld_abheben (Betrag);
    }
    
    int kunde::waehrung_waehlen()
    {
            std::cout << "In welcher Waehrung wollen sie Geld abheben? (Dollar/Euro)" << std::flush;
            enum Einheit {Dollar, Euro};
            std::cin >> waehrung;
    }
    

    ..
    Ich weiß, dass es schonmal lief, aber dann stürzte der Emacs-Server ab...

    Sieht jemand den Fehler? hab ich mich einfacgh nur vertippt? 😕



  • Wo ist denn Einheit definiert?



  • kunde.h Zeile 15 bzw kunde.c Zeile 33 (?)

    EDIT:

    Kompletter G++ output: (hatte noch ein paar *.gch dateien im Ordner)

    In file included from kunde.cpp:2:
    kunde.h:14: Fehler: »Einheit« bezeichnet keinen Typ
    kunde.cpp: In member function »int kunde::waehrung_waehlen()«:
    kunde.cpp:34: Fehler: »waehrung« wurde in diesem Gültigkeitsbereich nicht definiert
    In file included from main.cpp:1:
    kunde.h:14: Fehler: »Einheit« bezeichnet keinen Typ
    

    EDIT:

    Wenn ich das enum ... and den Anfang der Header-Datei schiebe und es in der kunde.cpp auskommentiere, sagt mir g++

    kunde.cpp: In member function »int kunde::waehrung_waehlen()«:
    kunde.cpp:34: Fehler: no match für »operator>>« in »std::cin >> ((kunde*)this)->kunde::Waehrung«
    /usr/lib/gcc/i686-pc-linux-gnu/4.3.3/include/g++-v4/istream:123: Anmerkung: Kandidaten sind: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(std::basic_istream<_CharT, _Traits>& (*)(std::basic_istream<_CharT, _Traits>&)) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-pc-linux-gnu/4.3.3/include/g++-v4/istream:127: Anmerkung:                  std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(std::basic_ios<_CharT, _Traits>& (*)(std::basic_ios<_CharT, _Traits>&)) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-pc-linux-gnu/4.3.3/include/g++-v4/istream:134: Anmerkung:                  std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(std::ios_base& (*)(std::ios_base&)) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-pc-linux-gnu/4.3.3/include/g++-v4/istream:170: Anmerkung:                  std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(bool&) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-pc-linux-gnu/4.3.3/include/g++-v4/istream:174: Anmerkung:                  std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(short int&) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-pc-linux-gnu/4.3.3/include/g++-v4/istream:177: Anmerkung:                  std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(short unsigned int&) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-pc-linux-gnu/4.3.3/include/g++-v4/istream:181: Anmerkung:                  std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(int&) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-pc-linux-gnu/4.3.3/include/g++-v4/istream:184: Anmerkung:                  std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(unsigned int&) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-pc-linux-gnu/4.3.3/include/g++-v4/istream:188: Anmerkung:                  std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(long int&) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-pc-linux-gnu/4.3.3/include/g++-v4/istream:192: Anmerkung:                  std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(long unsigned int&) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-pc-linux-gnu/4.3.3/include/g++-v4/istream:197: Anmerkung:                  std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(long long int&) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-pc-linux-gnu/4.3.3/include/g++-v4/istream:201: Anmerkung:                  std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(long long unsigned int&) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-pc-linux-gnu/4.3.3/include/g++-v4/istream:206: Anmerkung:                  std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(float&) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-pc-linux-gnu/4.3.3/include/g++-v4/istream:210: Anmerkung:                  std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(double&) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-pc-linux-gnu/4.3.3/include/g++-v4/istream:214: Anmerkung:                  std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(long double&) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-pc-linux-gnu/4.3.3/include/g++-v4/istream:218: Anmerkung:                  std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(void*&) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-pc-linux-gnu/4.3.3/include/g++-v4/istream:242: Anmerkung:                  std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(std::basic_streambuf<_CharT, _Traits>*) [with _CharT = char, _Traits = std::char_traits<char>]
    

    😮


  • Administrator

    andy89 schrieb:

    Wenn ich das enum ... and den Anfang der Header-Datei schiebe und es in der kunde.cpp auskommentiere, ...

    Das ist auch das einzig Richtige. Woher soll der Kompiler sonst wissen, was Einheit bedeuten soll? Er kennt dieses enum gar nicht, wenn du es davor nicht deklarierst.

    andy89 schrieb:

    sagt mir g++

    Man kann keine enum -Werte einlesen.
    Lies zum Beispiel einen int ein und wandle ihn dann in einen enum -Wert um.

    #include <iostream>
    
    enum Currency
    {
      Dollar,
      Euro
    };
    
    int main()
    {
      Currency currency;
    
      std::cin >> currency; // Fehler!
    
      int temp;
      std::cin >> temp; // Geht.
    
      // Bereichsprüfung von temp einfügen.
      currency = static_cast<Currency>(temp); // Geht.
    
      return 0;
    }
    

    Grüssli



  • Dravere schrieb:

    Man kann keine enum -Werte einlesen.

    Doch.

    std::istream& operator>> (std::istream& is, Currency& c)
    {
    	int temp;
    	is >> temp;
    
    	c = static_cast<Currency>(temp);
    	return is;
    }
    

    Oder man baut das Ganze zu einer Klasse aus - so kann man beispielsweise auch Formatierungen wie "$" oder "€"-Zeichen oder Dezimalpunkte abfragen.



  • 😕

    Dravere schrieb:

    Lies zum Beispiel einen int ein und wandle ihn dann in einen enum-Wert um.

    In wiefern unterscheidet sich jetzt deine Version zu der von Dravere?!

    Den Operator könnte man für so ziemlich alles missbrauchen. 😉 - Das hat aber nichts damit zu tun, ob es von Haus aus möglich ist..



  • drakon schrieb:

    In wiefern unterscheidet sich jetzt deine Version zu der von Dravere?!

    Ich bezog mich nur auf die Aussage, es wäre nicht möglich, einen Stream direkt in ein Enum einzulesen. Es klang nicht wie ein "von Haus aus nicht möglich", aber vielleicht habe ich Dravere auch falsch verstanden... 😉


  • Administrator

    Nexus schrieb:

    drakon schrieb:

    In wiefern unterscheidet sich jetzt deine Version zu der von Dravere?!

    Ich bezog mich nur auf die Aussage, es wäre nicht möglich, einen Stream direkt in ein Enum einzulesen. Es klang nicht wie ein "von Haus aus nicht möglich", aber vielleicht habe ich Dravere auch falsch verstanden... 😉

    Auch in deinem Code liest du keinen enum -Wert ein. Du verbirgst nur diese Unfähigkeit. Gut, ich hätte auch schreiben können, dass man keine enum -Werte direkt einlesen kann, aber darum ging es ja wirklich nicht. Ich bezog mich schliesslich auch auf den Code von andy89.

    Aber naja, besser es sei noch erwähnt, vielleicht wusste andy89 von diser Möglichkeit noch nicht. Vielleicht wären dann noch diese zwei Artikel lesenswert:
    http://magazin.c-plusplus.net/artikel/%DCberladung%20von%20Operatoren%20in%20CPlusPlus%20(Teil%201)
    http://magazin.c-plusplus.net/artikel/Ein-%20und%20Ausgabe%20in%20CPlusPlus%20-%20IO-Streams

    Oder gleich ein C++ Buch? 🙂

    Grüssli



  • Dravere schrieb:

    ...

    #include <iostream>
    
    enum Currency
    {
      Dollar,
      Euro
    };
    
    int main()
    {
      Currency currency;
    
      std::cin >> currency; // Fehler!
    
      int temp;
      std::cin >> temp; // Geht.
    
      // Bereichsprüfung von temp einfügen.
      currency = static_cast<Currency>(temp); // Geht.
    
      return 0;
    }
    

    Grüssli

    Soweit ich das jetzt verstanden habe, ist cin nur für die "Standardtypen" definiert, nicht für selbstdefinierte Typen.

    Aber ich kann den Wert, den ich haben will, jetzt nicht als String eingeben, sondern müsste ihn als int-Wert eingeben, oder?
    Wenn ich allerdings 0 eingebe (den Wert von Dollar in diesem Fall?), und es dann wieder ausgeben lasse

    ...
    std::cout << currency << std::endl;
    return 0;
    

    , erscheint bei des Ausgabe 0.
    Ist es auch möglich, direkt "Dollar" ausgeben zu lassen?


  • Administrator

    andy89 schrieb:

    Ist es auch möglich, direkt "Dollar" ausgeben zu lassen?

    Jedenfalls nicht auf diese Weise. Das Problem ist, dass ein enum -Wert nichts anderes als eine Ganzzahl ist. Es sind nämlich beschriftete konstante Ganzzahlen. Die Beschriftung ist aber nur für dich als Programmierer vorhanden, nach dem Kompilieren sind es nur noch Zahlen.

    Falls du den Namen ausgeben lassen möchtest, gibt es da verschiedene Möglichkeiten. Falls die enum -Werte fortlaufend sind und bei 0 beginnen, kann man sich ein Array von Namen dazumachen, also zum Beispiel so:

    enum Currency
    {
      Dollar, // beginnt bei 0
      Euro
    };
    
    char const* currencyNames[] = { "Dollar", "Euro" };
    

    Ansonsten kann man sich auch einer std::map<Currency, std::string> bedienen.
    http://www.cplusplus.com/reference/stl/map/

    Für das Einlesen geht es wohl nur über eine std::map<std::string, Currency> . Oder du kannst dir die Bimap von Boost holen, um den gleichen Container für das Lesen und Schreiben zu verwenden.
    http://www.boost.org/doc/libs/1_38_0/libs/bimap/doc/html/index.html

    Nur halt immer daran denken, den Container mit dem enum zu aktualisieren.

    Grüssli


Anmelden zum Antworten