Middle
Τι συμβαίνει κατά τη μετακίνηση ενός αντικειμένου τύπου std::string στην C++;
sobes.tech AI
Απάντηση από AI
Όταν μετακινείτε ένα std::string, η ιδιοκτησία του πόρου (μνήμης) μεταφέρεται από το αρχικό αντικείμενο στο στόχο. Αντί να αντιγράψετε το περιεχόμενο της συμβολοσειράς (χαρακτήρες), αντιγράφεται μόνο ο δείκτης προς το buffer, το μέγεθος και η χωρητικότητά του. Το αρχικό αντικείμενο βρίσκεται σε μια έγκυρη αλλά μη ορισμένη κατάσταση (συνήθως, ο δείκτης γίνεται μηδενικός, και το μέγεθος και η χωρητικότητα μηδενίζονται), αποτρέποντας την διπλή απελευθέρωση μνήμης. Αυτό είναι πολύ πιο γρήγορο από την πλήρη αντιγραφή, ειδικά για μακριές συμβολοσειρές.
#include <string>
#include <iostream>
#include <utility>
int main() {
std::string original = "Μια πολύ μεγάλη συμβολοσειρά που δεν θέλετε να αντιγράψετε";
std::cout << "Αρχικό (πριν από τη μεταφορά): " << original << std::endl;
// Μεταφέρουμε το original στο moved
std::string moved = std::move(original);
std::cout << "Μεταφέρθηκε (μετά τη μεταφορά): " << moved << std::endl;
// το original τώρα βρίσκεται σε μια έγκυρη αλλά μη ορισμένη κατάσταση.
// Η προσπάθεια χρήσης του original μετά τη μεταφορά χωρίς αρχικοποίηση είναι μη ορισμένη συμπεριφορά.
// Ωστόσο, πολλές υλοποιήσεις το επαναφέρουν σε μια κενή κατάσταση.
// std::cout << "Αρχικό (μετά τη μεταφορά): " << original << std::endl; // Επικίνδυνο!
return 0;
}
Ο κατασκευαστής μεταφοράς ή ο τελεστής ανάθεσης:
- Αναθέτει τον δείκτη στο buffer στον στόχο.
- Αναθέτει το μέγεθος και τη χωρητικότητα στον στόχο.
- Ορίζει τον δείκτη του buffer του αρχικού σε
nullptr. - Ορίζει το μέγεθος και τη χωρητικότητα του αρχικού σε 0.
Αυτό υλοποιείται χάρη στη σημασιολογία μεταφοράς (rvalue-αναφορές και ειδικοί κατασκευαστές/τελεστές).