Frage zu Strukturen und Funktionen



  • fr33g schrieb:

    std::map< chemicalElements, const std::string > elements
    

    Du meinst

    std::map<std::string, ChemicalElement> Elements;
    

    oder?



  • DocShoe schrieb:

    fr33g schrieb:

    std::map< chemicalElements, const std::string > elements
    

    Du meinst

    std::map<std::string, ChemicalElement> Elements;
    

    oder?

    Ja klar 😃 , sorry war mein Fehler, passiert mal eben so auf die schnelle 😉
    Danke für den Hinweis 🙂

    Lg freeG



  • Das "Ultra-Design" wäre natürlich ein Singleton mit mehreren Instanzen der Klasse (also allen verfügbaren Elementen), einer Zugriffsfunktion per String, die die deutsche Bezeichnung, die internationale Bezeichnung und das Elementsymbol durchsucht und, wenn verfügbar, die passende Instanz (sonst vielleicht eine Null-Instanz) zurückgibt, die man dann per Memberfunktion ausgeben kann oder ihre Informationen in einem String zusammengefasst bekommen kann, der dann ausgegeben werden kann. 😃



  • Ultra-Design und Singleton wirken geradezu parodisch, wenn man die parallele "Diskussion" in meinem Thread betrachtet (auch sonst). 😉



  • Kann mir mal jemand zeigen wie genau das mit der Map und dem Überladen in der Klasse funktionieren würde?Krieg das noch nicht so ganz hin.



  • fr33g schrieb:

    Ich würde mir eine Klasse chemicalElements erstellen, diese hat eben die verschiedenen Datenmember wie Ordnungszahl, Hauptgruppe, Periode, Massenzahl, Elektronegativität und so weiter. Dann überladest du für diese Klasse den Ausgabeoperator. Du erstellst dann alle Elemente und wirfst sie zum Beispiel in eine Map

    std::map< chemicalElements, const std::string > elements
    

    Nun ließt du die Eingabe vom User ein und machst eine Funktion, die deine Map nach dem eingegebenen Element durchsucht. Ist dieses Element gefunden gibst du es mittels

    cout << wasserstoff
    

    aus( du musst natürlich wie gesagt den Ausgabeoperator überladen haben.

    Ich würde das eher andersherum verwenden - der erste Template-Parameter von map<> ist der Suchschlüssel 😉

    @Babb: Wie weit bist du denn schon gekommen? Die Operator-Überladung brauchst du nicht unbedingt für den Anfang, da reicht es auch, eine Ausgabe-Methode für deine Klasse zu definieren.

    Zu der map:

    map<string,Element> Periodensystem;
    //Periodensystem füllen:
    Periodensystem["Wasserstoff"] = Element(1,"H",...);
    Periodensystem["Helium"]      = Element(2,"He",...);
    ...
    
    //Suchen und ausgeben
    cin>>name;
    map<string,Element>::iterator pos = Periodensystem.find(name);
    if(pos != Periodensystem.end())
      pos->print();
    else
      cout<<name<<" wurde noch nicht entdeckt"<<endl;
    


  • map<string,Element> Periodensystem; 
    //Periodensystem füllen: 
    Periodensystem["Wasserstoff"] = Element(1,"H",...); 
    Periodensystem["Helium"]      = Element(2,"He",...); 
    ... 
    
    //Suchen und ausgeben 
    cin>>name; 
    map<string,Element>::iterator pos = Periodensystem.find(name); 
    if(pos != Periodensystem.end()) 
      pos->print(); 
    else 
      cout<<name<<" wurde noch nicht entdeckt"<<endl;
    

    Und das soll einfach so in die Klasse? Ich nehm mal an,dass "Element"der Name der Struktur sein soll,in der die Elemente gespeichert sind und "Periodensystem" der Name der Map (oder meiner Klasse?) ist.

    Brauch ich (mehr als) den Header <map> ?Bisschen viele Fragen,ich weiß aber ich hab mich mit Maps noch nie auseinander gesetzt und auch mit Klassen habe ich in C++ noch nicht viel gearbeitet,also bin ich mit der Syntax kein bisschen vertraut.



  • Klar kannst du das alles in eine Klasse kapseln, in dem Fall solltest du die map<> selber eventuell umbenennen (und als privaten Member in die PeriodenSystem-Klasse packen). Der Code dort oben sollte nur demonstrieren, wie du die map verwenden kannst.



  • Ich geb dir mal ein Grundgerüst:

    ChemicalElement.h:

    #ifndef CHEMICAL_ELEMENT_H
    #define CHEMICAL_ELEMENT_H
    
    #include <string>
    
    class ChemicalElement
    {
        std::string international_name;
        std::string german_name;
        std::string element_symbol;
        int atomic_number;
        double element_weight;
    
        public:
        ChemicalElement(std::string const &p_international_name, std::string const &p_german_name, std::string const &p_element_symbol, int p_atomic_number, double p_element_weight);
        ChemicalElement();
        ~ChemicalElement(){}
    
        std::string GetInformationString();
    };
    
    #endif //CHEMICAL_ELEMENT_H
    

    ChemicalElement.cpp:

    #include "ChemicalElement.h"
    #include <map>
    #include <iostream>
    
    ChemicalElement::ChemicalElement(std::string const &p_international_name, std::string const &p_german_name, std::string const &p_element_symbol, int p_atomic_number, double p_element_weight)
      : international_name(p_international_name)
      , german_name(p_german_name)
      , element_symbol(p_element_symbol)
      , atomic_number(p_atomic_number)
      , element_weight(p_element_weight)
    {
    }
    
    ChemicalElement::ChemicalElement()
      : international_name("")
      , german_name("")
      , element_symbol("")
      , atomic_number(0)
      , element_weight(0.0)
    {
    }
    
    std::string ChemicalElement::GetInformationString()
    {
        //Hier die Informationen zusammenstellen und zurückgeben!
    }
    
    std::map<std::string, ChemicalElement> element_map;
    
    void init_element_map()
    {
        element_map["Wasserstoff"] = ChemicalElement("Wasserstoff", "Hydrogenium", "H", 1, 1.004);
        //andere Elemente hinzufügen
    }
    
    int main()
    {
        init_element_map();
    
        while(true)  //hier kann man natürlich noch eine "Nochmal?-Abfrage" einbauen
        {
            std::string element_name;
            //Element abfragen
    
            std::map<std::string, ChemicalElement>::iterator iter = element_map.find(element_name);
            if(iter == element_map.end())
            {
                std::cout << "Element existiert nicht!\n";
            }
            else
            {
                std::cout << iter->second.GetInformationString();
            }
        }
    }
    

    (OK, das ist jetzt noch nicht perfekt gekapselt, aber es zeigt dir schonmal die Syntax 😉 )



  • ChemicalElement();
    

    Ich mag diese Angewohnheit, Konstruktoren ohne sinnvolle Initialisierung einfach mal grundsätzlich anzubieten, nicht besonders. Hier ist halt etwas schade, dass man ohne Defaultkonstruktor den std::map::operator[] nicht mehr benutzen kann, dann müsste man eben zu insert() greifen.

    ~ChemicalElement(){}
    

    Wozu?

    std::string GetInformationString();
    

    Hier fehlt eine const -Qualifizierung.

    std::map<std::string, ChemicalElement> element_map;
    

    Würde ich eher lokal deklarieren und übergeben. Eventuell wäre typedef nicht schlecht.



  • @Nexus:
    Konstruktor - richtig, den habe ich erst nachher eingefügt, weil mir eingefallen ist, dass es sonst für Einsteiger noch komplizierter wird.
    Destruktor - Angewohnheit, den mit dazu zu schreiben
    const - richtig, vergessen, wenn auch hier nicht so wichtig
    typedef - mag ich in dem Fall nicht so (zumindest bei zweifacher Verwendung), Lokalisierung stimmt, ich habe ja gesagt, ich würde es am liebsten in einer Art Singleton machen, das wäre jetzt für den TE AFAIK aber zu kompliziert.



  • CStoll schrieb:

    fr33g schrieb:

    Ich würde mir eine Klasse chemicalElements erstellen, diese hat eben die verschiedenen Datenmember wie Ordnungszahl, Hauptgruppe, Periode, Massenzahl, Elektronegativität und so weiter. Dann überladest du für diese Klasse den Ausgabeoperator. Du erstellst dann alle Elemente und wirfst sie zum Beispiel in eine Map

    std::map< chemicalElements, const std::string > elements
    

    Nun ließt du die Eingabe vom User ein und machst eine Funktion, die deine Map nach dem eingegebenen Element durchsucht. Ist dieses Element gefunden gibst du es mittels

    cout << wasserstoff
    

    aus( du musst natürlich wie gesagt den Ausgabeoperator überladen haben.

    Ich würde das eher andersherum verwenden - der erste Template-Parameter von map<> ist der Suchschlüssel 😉

    fr33g schrieb:

    DocShoe schrieb:

    fr33g schrieb:

    std::map< chemicalElements, const std::string > elements
    

    Du meinst

    std::map<std::string, ChemicalElement> Elements;
    

    oder?

    Ja klar 😃 , sorry war mein Fehler, passiert mal eben so auf die schnelle 😉
    Danke für den Hinweis 🙂

    Lg freeG

    😉

    Lg freeG



  • Vielen Dank,wxSkip!
    Hat sehr geholfen die Syntax zu verstehen.Ich setz den Entwurf dann wohl morgen um.
    Vielen Dank an die vielen hilfreichen und extrem schnellen Antworten,nettes Forum 🙂


Anmelden zum Antworten