operator++()



  • In meinem Buch ist folgendes Codebeispiel zum ++-Operator:

    const Counter& operator++() 
    {
        ++itsVal;
        return *this;
    }
    

    Wie kann diese "Funktion" aber denn Wert "itsVal" durch das vorangestellte ++ verändern, wenn die Funktion als konstant deklariert ist?



  • Der Rückgabewert ist Konstant, nicht die Methode.

    Es soll verhindern das Du:

    i++++++++ schreiben kannst.



  • Jo, wenn man mal davon absieht, dass das der Prefix-Operator ist 😉

    Ich find das aber schwachsinnig. Beim nicht-überladenen Prefix-Inkrement ist ++ ++ ++ ++ a auch erlaubt, warum sollte man das bei einem überladenen verbieten? => nicht-const Referenz zurückgeben.

    Griese: Konstante Memberfunktionen deklariert man so:

    class Blub {
      public:
        void funktion() const { ... }
    };
    


  • Ich sehe ehrlich gesagt keinen Sinn darin, Counter als konstantes Objekt zurückzugeben. Oder habe ich da etwas übersehen und sollte in Zukunft alle Objekte, die zurückgegeben werden konstant machen?



  • Bashar schrieb:

    Ich find das aber schwachsinnig. Beim nicht-überladenen Prefix-Inkrement ist ++ ++ ++ ++ a auch erlaubt, warum sollte man das bei einem überladenen verbieten? => nicht-const Referenz zurückgeben.

    Naja, man soll sich bestenfalls so verhalten wie es die internen Datetypen auch machen. Da trifft dann das zu was Bashar sagte.

    Und die op für ++i und i++ schmeiss ich generell durcheinander O🤡



  • Frage: Warum wird beim Code

    //
    #include <iostream>
    #include <cstdio>
    using namespace std;
    
    class Counter
    {
        private:
            int itsVal;
    
        public:
            Counter(): itsVal(0) { cout<<"Counter-Konstruktor...\n"; }
            ~Counter() { cout<<"Counter-Destruktor...\n"; }
    
            int getVal() const { return itsVal; }
    
            Counter operator++() {
                cout<<"operator++()...\n";
                ++itsVal;
                return *this;
            }
    };
    
    void main()
    {
        Counter i;
        cout<<"i: "<<i.getVal()<<endl;
        ++i;
        cout<<"i: "<<i.getVal()<<endl;
        ++i;
        cout<<"i: "<<i.getVal()<<endl;
    
        getchar();
    }
    

    ein Counter Objekt erstellt, und zwei abgebaut (Konstruktor-Aufruf 1 mal, Destruktor-Aufruf 2 mal)?



  • Es werden genausoviele Objekte erzeugt wie zerstört. Aber du läßt nur beim Standardkonstruktor eine Meldung ausgeben ... die anderen werden bei der Rückgabe aus operator++ durch den Kopierkonstruktor erzeugt. Wenn du den ebenfalls implementierst, wirst du feststellen, dass die Gesamtzahl der Konstruktoraufrufe mit der Gesamtzahl der Destruktoraufrufe übereinstimmt.

    Wieso gibst du das Objekt eigentlich nicht per Referenz zurück?



  • Danke für deine Antwort, Bashar.

    Ich habe ein wenig rumgespielt, wegen der obigen const-Frage.



  • Weil Du im operator++ by value zurückgibst, das heißt es wird eine Kopier erstellt, und das geht mit dem Copy-Konstruktor. Zerstört wird sie aber mit dem normalen Destruktor (wie auch sont).

    Wenn Du das überprüfen willst:

    Copy-Ctor geht so: Counter(const Counter & other);
    Aber ich würde Dir empfehlen by reference zurückzugeben.

    Also so:

    Counter & operator++()
    {
      // ...
    }
    

    Das spart nämlich eine Kopie.

    MfG Jester



  • Ohne Referenz wäre die Ausgabe hier

    int a = 10;
    ++a = 20;
    std::cout << a;
    

    11 und nicht 20, weil die 20 der Kopie zugewiesen werden würde.

    MfG MAV


Anmelden zum Antworten