C++ Move Constructor

C Move Constructor



Ο προγραμματισμός C++ είναι η καλύτερη γλώσσα καθώς μας διευκολύνει με ένα ευρύ φάσμα λειτουργιών, κατασκευαστών, αρχείων κεφαλίδων, κλάσεων και πολλά άλλα, κάνοντας την κωδικοποίηση πιο ενδιαφέρουσα και ευκολότερη. Ένας από τους κατασκευαστές στον προγραμματισμό C++ είναι ο κατασκευαστής «move». Ο κατασκευαστής «μετακίνησης» είναι ένα μοναδικό είδος κατασκευαστή που επιτρέπει τη μεταφορά της ιδιοκτησίας μιας δυναμικά εκχωρημένης μνήμης ή άλλων πόρων από το ένα αντικείμενο στο άλλο με αποτελεσματικό και συνειδητό τρόπο.

Στον προγραμματισμό της C++, εισήχθησαν κατασκευαστές 'μετακίνησης' για να μειώσουν τον διπλασιασμό και να βελτιώσουν την απόδοση. Παίζει καθοριστικό ρόλο στη βελτίωση της απόδοσης ελαχιστοποιώντας τις λειτουργίες αντιγραφής. Αυτός ο οδηγός διερευνά σε βάθος τον κατασκευαστή 'μετακίνηση' στον προγραμματισμό C++.







Παράδειγμα 1:

Για να ξεκινήσουμε τον κώδικα εδώ, συμπεριλαμβάνουμε τα αρχεία κεφαλίδας 'iostream' και 'string' που θα κάνουν τον κώδικά μας να εκτελείται τέλεια, καθώς πολλές συναρτήσεις δηλώνονται σε αυτά τα αρχεία κεφαλίδας. Όταν πρέπει να χρησιμοποιήσουμε τη δήλωση 'cout', χρησιμοποιείται το αρχείο κεφαλίδας 'iostream' αφού αυτή η συνάρτηση δηλώνεται μέσα σε αυτό. Όταν πρέπει να δουλέψουμε με τα δεδομένα τύπου string, το αρχείο κεφαλίδας 'string' είναι απαραίτητο.



Μετά από αυτό, το 'namespace std' προστίθεται κάτω από αυτά τα αρχεία κεφαλίδας. Στη συνέχεια, κατασκευάζουμε μια τάξη εδώ. Το όνομα της τάξης είναι 'Μετακίνηση'. Κάτω από αυτό, προστίθεται η λέξη-κλειδί 'ιδιωτική' στην οποία δηλώνουμε μια ιδιωτική μεταβλητή συμβολοσειράς με το όνομα 'my_str'. Τώρα, τοποθετούμε τη λέξη-κλειδί 'δημόσια' όπου προσθέτουμε τον ορισμό του προεπιλεγμένου κατασκευαστή. Περνάμε το 'This is the default string here' στο 'my_str' ως παράμετρο και αφήνουμε κενό τον προεπιλεγμένο κατασκευαστή.



Μετά από αυτό, αντιγράφουμε τον ορισμό του κατασκευαστή και αρχικοποιούμε το 'my_str' στο 'my_obj.my_str'. Κάτω από αυτό, εκτυπώνουμε μια γραμμή και, στη συνέχεια, τοποθετούμε τον ορισμό του κατασκευαστή 'move'. Εδώ, αρχικοποιούμε ξανά το 'my_str' με το 'my_obj.my_str'. Δεν προσθέτουμε καμία δήλωση κάτω από αυτό. είναι άδειο. Μετά από αυτό, δηλώνουμε μια συνάρτηση με το όνομα 'displayMyObject()' τύπου συμβολοσειράς και χρησιμοποιούμε το 'return str' έτσι ώστε να επιστρέφει τη συμβολοσειρά.





Τοποθετούμε την καθολική συνάρτηση 'new_temp' στον τύπο 'move'. Κάτω από αυτό, έχουμε το 'return temp' που επιστρέφει το αντικείμενο τύπου move. Τώρα, τοποθετούμε τον κώδικα προγράμματος οδήγησης 'main()' και το 'new_obj1' του τύπου 'move' και παίρνουμε τον κατασκευαστή 'move' από το 'rvalue'. Στη γραμμή μπροστά, τοποθετούμε το 'new_obj1.displayMyObject()' για να λάβουμε τον κατασκευαστή 'move' από το 'lvalue'. Μετά από αυτό, καλούμε τον κατασκευαστή 'move' με το αντικείμενο 'my_obj1'. Στη συνέχεια, μεταβιβάζουμε την κυριότητα του 'my_obj1' στο άλλο αντικείμενο που είναι το 'my_obj2'.

Κωδικός 1:

#include

#include

χρησιμοποιώντας χώρο ονομάτων std ;

τάξη Κίνηση

{

ιδιωτικός :
συμβολοσειρά my_str ;
δημόσιο :
Κίνηση ( ) : my_str ( 'Αυτή είναι η προεπιλεγμένη συμβολοσειρά εδώ' )
{
}
Κίνηση ( συνθ Κίνηση & my_obj ) : my_str ( my_obj. my_str )
{


cout << 'Έγινε επίκληση του κατασκευαστή αντιγραφής, η μετακίνηση απέτυχε! \n ' ;

}
Κίνηση ( Κίνηση && my_obj ) : my_str ( κίνηση ( my_obj. my_str ) )
{
}
συμβολοσειρά displayMyObject ( )
{
ΕΠΙΣΤΡΟΦΗ my_str ;
}
} ;
Μετακίνηση new_temp ( Μετακίνηση tmp )
{
ΕΠΙΣΤΡΟΦΗ tmp ;
}
ενθ κύριος ( )
{
Μετακίνηση new_obj1 = new_temp ( Κίνηση ( ) ) ;


cout << 'before move() call : new_obj1 = ' << new_obj1. displayMyObject ( ) << endl ;

Μετακίνηση new_obj2 = κίνηση ( new_obj1 ) ;

cout << 'after move() κλήση κατασκευαστή : new_obj1 = ' << new_obj1. displayMyObject ( ) << endl ;

cout << 'after move() κλήση κατασκευαστή : new_obj2 = ' << new_obj2. displayMyObject ( ) << endl ;

ΕΠΙΣΤΡΟΦΗ 0 ;

}

Παραγωγή:

Η έξοδος αποδίδει ότι πριν καλέσετε τη μέθοδο 'move()', το 'new_obj1' περιέχει την προεπιλεγμένη συμβολοσειρά. Αλλά μετά την κλήση της μεθόδου move() της κλάσης 'Move', το 'my_obj1' περιέχει μια κενή συμβολοσειρά και το 'my_obj2' έχει την προεπιλεγμένη συμβολοσειρά.



Παράδειγμα 2:

Εδώ, συμπεριλαμβάνουμε ένα ακόμη αρχείο κεφαλίδας που είναι το αρχείο κεφαλίδας 'διανυσματικό'. Το συμπεριλαμβάνουμε κάθε φορά που πρέπει να χειριστούμε τις πράξεις στα διανύσματα. Η κλάση που δημιουργούμε εδώ είναι η κλάση 'Μετακίνηση'. Δημιουργούμε επίσης έναν κατασκευαστή 'δημόσιο' εδώ στον οποίο δηλώνουμε τον πρωτογενή δείκτη 'int* value' ως δεδομένα μέλους κλάσης. Κάτω από αυτό, έχουμε το 'public' στο οποίο τοποθετούμε τον κατασκευαστή 'Move' και περνάμε το 'int v1' ως παράμετρό του.

Μετά από αυτό, δηλώνουμε τα αντικείμενα σε ένα σωρό. Αρχικοποιούμε την 'τιμή' με 'new int' και την '*τιμή' με 'v1'. Στη συνέχεια, τοποθετήστε το 'cout' όπου προσθέτουμε μια γραμμή που εκτυπώνεται όταν εκτελούμε τον κώδικα. Κάτω από αυτό, χρησιμοποιούμε τον κατασκευαστή 'αντιγραφή'. Αυτός ο κατασκευαστής «αντιγραφής» αντιγράφει τα δεδομένα δημιουργώντας ένα βαθύ αντίγραφο. Τοποθετούμε τον κατασκευαστή «Μετακίνηση» και περνάμε το «Move&& new_source» ως παράμετρό του. Κάτω από αυτό, τοποθετούμε το 'cout' που βοηθά στην εμφάνιση της απαιτούμενης δήλωσης.

Εισαγάγουμε τη λέξη-κλειδί 'nullptr' για να προσδιορίσουμε εάν ένας δείκτης είναι κενός πριν από τη χρήση της αναφοράς. Τώρα, τοποθετούμε επίσης τον καταστροφέα '~Move()' στον οποίο τοποθετούμε τη συνθήκη 'if' που επαληθεύει εάν η 'τιμή' δεν είναι ίση με 'nullptr'. Όταν επαληθευτεί αυτή η συνθήκη, εκτελείται η παρακάτω δήλωση. Εάν αυτή η συνθήκη δεν επαληθευτεί, παρακάμπτει τη δήλωση «cout» που υπάρχει μετά τη συνθήκη «αν» και μετακινείται προς το τμήμα «άλλο».

Μετά από αυτό, χρησιμοποιούμε τη λέξη-κλειδί «διαγραφή» που βοηθά στην κατανομή ενός αντικειμένου ή μπορούμε να πούμε ότι απελευθερώνει τη μνήμη που εκχωρείται στο στοιχείο δεδομένων του αντικειμένου. Τώρα, καλούμε τη μέθοδο 'main()' εδώ και δημιουργούμε το διάνυσμα της κλάσης 'Move' με το όνομα 'my_vec'. Μετά από αυτό, χρησιμοποιούμε τη συνάρτηση 'push_back()' που βοηθά στην εισαγωγή μιας τιμής στο τελικό σημείο ενός διανύσματος. Το αρχείο κεφαλίδας 'διάνυσμα' περιέχει αυτή τη λειτουργία. Αρχικά, εισάγουμε το '39' στο διάνυσμα. Στη συνέχεια, εισάγεται το '57' και εισάγεται επίσης το '91' χρησιμοποιώντας τη μέθοδο 'push_back()'.

Κωδικός 2:

#include

#include <διάνυσμα>

χρησιμοποιώντας χώρο ονομάτων std ;

τάξη Κίνηση {

ιδιωτικός :
ενθ * αξία ;
δημόσιο :
Κίνηση ( ενθ v1 )
{
αξία = νέος ενθ ;
* αξία = v1 ;

cout << 'Ο κατασκευαστής καλείται'

<< v1 << endl ;

} ;
Κίνηση ( συνθ Κίνηση & νέα_πηγή )
: Κίνηση { * νέα_πηγή. αξία }
{


cout << 'Το Copy Constructor ονομάζεται -'

<< 'Βαθύ αντίγραφο για'

<< * νέα_πηγή. αξία

<< endl ;

}
Κίνηση ( Κίνηση && νέα_πηγή )
: αξία { νέα_πηγή. αξία }
{


cout << 'Move Constructor for'

<< * νέα_πηγή. αξία << endl ;

νέα_πηγή. αξία = nullptr ;

}
~ Μετακίνηση ( )
{
αν ( αξία ! = nullptr )


cout << 'Ο καταστροφέας καλείται'

<< * αξία << endl ;

αλλού

cout << 'Ο καταστροφέας ονομάζεται'

<< 'για nullptr'

<< endl ;

διαγράφω αξία ;

}

} ;

ενθ κύριος ( )

{

διάνυσμα < Κίνηση > το πράγμα μου ;

το πράγμα μου. push_back ( Κίνηση { 39 } ) ;
το πράγμα μου. push_back ( Κίνηση { 57 } ) ;
το πράγμα μου. push_back ( Κίνηση { 91 } ) ;
ΕΠΙΣΤΡΟΦΗ 0 ;


}

Παραγωγή:

Αυτό δείχνει ότι αντί να χρησιμοποιήσουμε τη συνάρτηση «αντιγραφή», πρέπει να χρησιμοποιήσουμε τη λειτουργία «μετακίνηση» για να αποτρέψουμε την άσκοπη κλήση στη λειτουργία «αντιγραφή». Ο κατασκευαστής 'move' καλείται εδώ όταν αρχικοποιούμε το αντικείμενο με ένα προσωρινό αντικείμενο ή κάποιο αντικείμενο που θα καταστραφεί. Αντί να χειριστεί ένα βαθύ αντίγραφο των δεδομένων, ο κατασκευαστής «μετακίνησης» μετατοπίζει την ιδιοκτησία των πόρων από το ένα αντικείμενο στο άλλο.

συμπέρασμα

Σε αυτόν τον οδηγό, εξερευνήσαμε τον κατασκευαστή 'μετακίνηση'. Εξηγήσαμε ότι ο κατασκευαστής 'μετακίνηση' στον προγραμματισμό C++ είναι μια μοναδική μέθοδος για την αποτελεσματική μετεγκατάσταση των πόρων ενός αντικειμένου σε άλλο αντικείμενο. Συζητήσαμε ότι η κλήση του κατασκευαστή 'μετακίνηση' έχει μικρότερο κόστος, καθιστώντας τον κώδικα πιο αποδοτικό στη μνήμη. Εξερευνήσαμε το γεγονός ότι ο κατασκευαστής 'move' είναι ένα ισχυρό χαρακτηριστικό στον προγραμματισμό C++. Χρησιμοποιήσαμε επίσης τα πρακτικά παραδείγματα για να επεξηγήσουμε την έννοια του κατασκευαστή 'move' και δείξαμε τα οφέλη απόδοσης από τη χρήση του κατασκευαστή 'move' στον προγραμματισμό C++.