Operatorenüberladung - Problem...



  • Hallo ich habe ein Problem, oder ich verstehe nicht ganz die Operatorenüberladung, spezifischer gesehen, die des Zuweisungs-Operatoren..

    Mein Problem, ich habe Folgende Klasse:

    class myString{
        string value;
    
        public:
            myString operator=(string v1);
    
            int toInt();
            float toFloat();
            double toDouble();
    };
    
    int myString::toInt()
    {
        stringstream ssStream(this->value);
        int iReturn;
        ssStream >> iReturn;
    
        return iReturn;
    }
    
    float myString::toFloat()
    {
        stringstream ssStream(this->value);
        float fReturn;
        ssStream >> fReturn;
    
        return fReturn;
    }
    
    double myString::toDouble()
    {
        stringstream ssStream(this->value);
        double dReturn;
        ssStream >> dReturn;
    
        return dReturn;
    }
    
    myString myString::operator=(string v1){
        this->value = v1;
        return *this;
    };
    

    Diese verwende ich in einer Structure:

    struct MyGameConfigStructure{
                myString Value;
                string ConfigName;
        };
    MyGameConfigStructure MyGameConfig[255];
    

    Die Zuweisung in die Value der Structure funktioniert ohne Probleme, doch wenn ich versuche über den = Operator mir den Wert in eine Strin Variable zu schreiben, dann bekomme ich folgenden Fehler:

    error: no match for 'operator=' in 'ReturnVar = ((Game*)this)->Game::MyGameConfig[i].Game::MyGameConfigStructure::Value'
    

    Hier noch die entsprechende Code-Stelle:

    ReturnVar = this->MyGameConfig[i].Value;
    

    i ist ein 'int' Variable...
    ReturnVar ist eine 'string' Varaible

    ich hab mir soviel gedacht, dass ich einen Operatoren definieren muss, der auf der linken Seite 'string' stehen hat und als Parameter eine Variable mit dem Typen 'myString' hat.

    daraus gekommen ist folgendes:

    string myString::operator=(myString v1){
        return v1->value;
    };
    

    Aber irgendwie funktioniert das nicht, die Fehlermeldung bleibt...
    Was mache ich Falsch?



  • ReturnVar = this->MyGameConfig[i].Value;
    bedeutet
    "string = myString;"

    du sprichst also den operator
    string& string::operator= ( myString const& val )
    an, den es nicht gibt.

    1.Tipp: Les dir was zum Thema Referenzen durch (das ist das '&').
    2.Tipp: Dein myString sollte eine Funktion oder evtl. einen Operator besitzen, mit dem man ihn zu einem string konvertieren kann.
    oder du vererbst ihm gleich den string.
    3.Tipp: Beim Zuweisungsoperator gibt das objekt normalerweise eine Referenz und keine Kopie von sich selbst zurück.
    strings sollten auch über Referenz übergeben werden, da sonst der ganze inhalt nchmal koiert wird (kann aber sein, dass das bei strings optimiert wird, da sie dem compiler bekannt sind)
    Bsp:

    myString& myString::operator=(string const& v1){
        value = v1;
        return *this;
    };
    

    // edit
    Besipiele zu Tipp 2:

    // per Funktion
    void myString::cpy_to( string& emp ) const { emp = value; }
    string myString::to_string() const { return value; } // schlecht, eine kopie wird evtl erzeugt.
    string const& myString::to_string() const { return value; }
    // weiß nicht ob das schlau ist -> abwarten, was die andren sagen...
    
    // per Operator
    // 1. weiß nicht ob das schlau ist -> abwarten, was die andren sagen...
    // 2. genauso, wie die letzten beiden Funktionen
    myString::operator string() const { return value; }
    myString::operator string const&() const { return value; }
    
    // per Vererbung
    class myString : string
    {
    public:
    	int toInt();
    	float toFloat();
    	double toDouble();
    };
    


  • ich hab mir einfach eine:

    string myString::toString()
    {
        return this->value;
    }
    

    Funktion gemacht und nu geht alles, ausserdem habe ich bei meiner operator Funktion das als Referenz geändert, ich weiß was eine Referenz ist 😉 da es aber auch ohne ging, hab ich mir gedacht dasses nicht unbedingt notwendig ist.



  • hm,du hättest auch einfach

    ReturnVar = this->MyGameConfig[i].Value.value

    schreiben können. (aber das ist nicht OOP-verschleierungsmäßig genug ^^)

    //edit:
    nochwas: vor die Beispiele zu Tipp 2 sollte man vllt 'inline' schreiben, die toString()-Variante sollte dan gleichbedeutent mit .value sein (sollte!).



  • wandrer schrieb:

    (aber das ist nicht OOP-verschleierungsmäßig genug ^^)

    Jo hab ich mir auch gedacht :), ausserdem entspricht es nicht dem OOP Konzept, meines erachtens nach...



  • Ich hab noch einen Fehler im Beispiel "per Vererbung" entdeckt.
    public vergessen (gewohnheit: struct).

    class myString : public string
    {
    public:
        int toInt() const; // nebenbei ...
        float toFloat() const;
        double toDouble() const;
    };
    

    das ist, glaub ich, die schönste/OOP Art das Problem zu lösen.
    hier kannst Du natürlich auch toString() wieder mit einbaun, falls du jetzt schon überall toString() geschrieben hast (das ist der Vorteil der "Verschleierung").



  • Warum aber eigentlich dieses 'const' hinter den Funktionsnamen?
    Wenn ich ja doch eigentlich dynamische Werte einsetze, also nicht im Code-Definierte???

    Ansonsten werd ich das toString() nutzen, weil der Aufwand geringer ist und mein Verständniss von C++ Klassen noch etwas gering ist... Ich komme von der Interpretersprache PHP, wo halt einiges anders ist, aber aufs meiste hab ich mich ja schon umgewöhnt.

    Ich danke auf jeden Fall 🙂



  • const bedeutet hier, dass das Objekt selbst konstant bleibt.
    d.h. z.B. in der Funktion "toInt()" kann das Element "value" nicht verändert werden.
    Man könnte sich
    int myString::toInt() const
    auch (prozedureal) als
    int toInt(myString const& text)
    vorstellen.
    const sollte man überall hinter Funktionen stellen, in denen die Elemente (Member) nicht verändert werden, sonst kommen später andauernd Meldungen, dass Qualifizierer verloren gehn (was norm. leicht zu beheben ist).
    Tutorials findet man in Massen auf der Startseite.



  • Wenn man const verwendet sollte man überall const verwenden, also auch bei Memberfunktionen.
    Ansonsten stehst du schnell vor dem Problem dass du irgendwo eine const Referenz auf ein Objekt hast, aber eine Memberfunktion dieses Objektes aufrufen musst (eine Memberfunktion die das Objekt nicht verändert). Wenn die Memberfunktion aber alle "non-const" sind, dann darfst du sie nicht aufrufen. Auch doof.
    In so einem Fall dann const_cast einzusetzen wäre IMHO schauderhaft, also... wenn const dann überall const wo es hingehört.


Anmelden zum Antworten