move assignment operator



  • 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