Middle
Co się dzieje podczas przenoszenia obiektu typu std::string w C++?
sobes.tech AI
Odpowiedź od AI
Przenosząc std::string, własność zasobu (pamięci) jest przekazywana z obiektu źródłowego do docelowego. Zamiast kopiować zawartość łańcucha (znaki), kopiowany jest tylko wskaźnik do bufora, jego rozmiar i pojemność. Obiekt źródłowy znajduje się wtedy w stanie ważnym, ale nieokreślonym (zwykle wskaźnik staje się nullem, a rozmiar i pojemność są zerowane), co zapobiega podwójnemu zwolnieniu pamięci. Jest to znacznie szybsze niż pełne kopiowanie, szczególnie dla długich łańcuchów.
#include <string>
#include <iostream>
#include <utility>
int main() {
std::string original = "Bardzo długi łańcuch, którego nie chcesz kopiować";
std::cout << "Oryginał (przed przeniesieniem): " << original << std::endl;
// Przenosimy original do moved
std::string moved = std::move(original);
std::cout << "Przeniesione (po przeniesieniu): " << moved << std::endl;
// original jest teraz w stanie ważnym, ale nieokreślonym.
// Próba użycia original po przeniesieniu bez inicjalizacji jest nieokreślonym zachowaniem.
// Jednak wiele implementacji resetuje go do stanu pustego.
// std::cout << "Oryginał (po przeniesieniu): " << original << std::endl; // Niebezpieczne!
return 0;
}
Konstruktor przenoszący lub operator przypisania:
- Przypisuje wskaźnik do bufora do obiektu docelowego.
- Przypisuje rozmiar i pojemność do obiektu docelowego.
- Ustawia wskaźnik na buforze obiektu źródłowego na
nullptr. - Ustawia rozmiar i pojemność obiektu źródłowego na 0.
Jest to realizowane dzięki semantyce przenoszenia (referencje rvalue i specjalne konstruktory/operatorzy).