move assignment operator



  • niko1 schrieb:

    wenn die daten verschoben werden, dann ist der stack natuerlich empty.
    muss den counter noch ruecksetzen...willst du auf das raus?

    Ja. Trotzdem ist dein Stack danach im Eimer, du kannst ihn nicht mehr benutzen.



  • d.h. der move assignment operator macht hier keinen sinn?



  • niko1 schrieb:

    d.h. der move assignment operator macht hier keinen sinn?

    Was ist hier?
    Deine main-Funktion ist sinnlos, aber für eine Funktion die einen Stack füllt und dann zurück liefert könnte es sinnvoll sein.



  • kann jemand ein beispiel posten wo der move assignment operator / move constructor sinn macht?


  • Mod

    niko1 schrieb:

    kann jemand ein beispiel posten wo der move assignment operator / move constructor sinn macht?

    Davon gibt es bestimmt genug, dass du welche im Netz findest. Das #1-Beispiel ist sicherlich ein Smart-Pointer wie unique_ptr .

    Siehe hier, die Zeilen 119-147.



  • Stack(Stack&& other)
        : count(other.count)
        , data(std::move(other.data))
    {
        other.count = 0;
    }
    
    Stack& operator = (Stack other)
    {
        swap(other);
        return *this;
    }
    
    void swap(Stack& other)
    {
        using std::swap;
        swap(count, other.count);
        swap(data, other.data);
    }
    

  • Mod

    @Kellerautomat: Warum Copy&Swap und nicht einfach defaulten?



  • update:

    #include <iostream> 
    #include <algorithm> 
    #include <cassert> 
    #include <array> 
    using namespace std; 
    
    #define SIZE 256 
    
    class Stack { 
    private: 
        unsigned int count; 
    
    public: 
        array<int, SIZE> data; 
    
        Stack(): count(0) {} 
    
        Stack(const Stack &s) { 
        	cout << "Stack(const Stack &s) called" << endl;
            std::copy(s.data.begin(), s.data.end(), data.begin()); 
            count = s.count; 
        } 
    
        Stack(Stack &&s) {
        	cout << "Stack(Stack &&s) called" << endl;
        	data = std::move(s.data); 
            count = std::move(s.count); 
            s.count = 0;
        } 
    
        Stack& operator=(const Stack &s) { 
        	cout << "Stack& operator=(const Stack &s) called" << endl;
            if(this != &s) { 
                std::copy(s.data.begin(), s.data.end(), data.begin()); 
                count = s.count; 
            } 
    
            return *this; 
        } 
    
        Stack& operator=(Stack &&s) {
        	cout << "Stack& operator=(Stack &&s) called" << endl;
            if(this != &s) { 
       			data = std::move(s.data); 
                count = std::move(s.count); 
                s.count = 0;
            } 
    
            return *this; 
        } 
    
        void push(int value) { 
            if(count < SIZE) {      
                data[count] = value; 
                count++; 
                return; 
            } 
    
            throw("stack is full"); 
        }   
    
        int pop() { 
            if(count > 0) { 
                int element = data[count-1]; 
                count--; 
                return element; 
            } 
    
            throw("stack is empty"); 
        } 
    
        bool empty() { 
            return count == 0; 
        } 
    }; 
    
    int main() { 
        Stack s; 
    
        s.push(1); 
        s.push(2); 
        s.push(3); 
    
        Stack a; 
        a = s;
      	cout << "empty: " << s.empty() << endl;
    
        while(!a.empty()) { 
            cout << a.pop() << endl; 
        } 
    
        Stack b; 
        b = std::move(s); 
      	cout << "empty: " << s.empty() << endl;
    
        while(!b.empty()) { 
            cout << b.pop() << endl; 
        }
    
      	Stack x;
      	Stack y(std::move(x));
    
        return 0;   
    }
    


  • warum uebergibst du den Stack im copy construktor nicht per referenz? ->

    Stack& operator = (Stack other)
    


  • Weil der Parameter hier in der Funktion ohnehin kopiert werden muss.
    Siehe auch hier etwas ausführlicher.
    https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Copy-and-swap



  • wie kann copy elision and copy-and-swap idiom auf self assignment pruefen?



  • Gar nicht. Das ist auch nicht zwingend notwendig.
    Wenn du das unbedingt machen willst musst du halt die andere Version nehmen.



  • ist folgendes ein potentielles problem? der compiler meldet auch keinen fehler, soll das so sein?

    Stack s(s);
    


  • niko1 schrieb:

    ist folgendes ein potentielles problem? der compiler meldet auch keinen fehler, soll das so sein?

    Stack s(s);
    

    Das Problem existiert, ist aber nur theoretischer Natur.

    int main()
    {
      std::string s	= s;
      std::cout << s; // Programm stürzt ab.
    }
    

    Kein normaler Mensch schreibt sowas.

    Selbstzuweisung über operator= kann hingegen viel einfacher vorkommen wegen Aliasing. Beim Kopierkonstruktor ist das dagegen ein non-issue.


Anmelden zum Antworten