Sobes.tech
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-αναφορές και ειδικοί κατασκευαστές/τελεστές).