Sobes.tech
Middle

Какво се случва при преместване на обект от тип std::string в C++?

sobes.tech AI

Отговор от AI

Когато премествате std::string, собствеността върху ресурса (паметта) се прехвърля от изходния обект към целевия. Вместо да копирате съдържанието на низа (символите), се копира само указателят към буфера, неговият размер и капацитет. Изходният обект остава в валидно, но неопределено състояние (обикновено указателят става нулев, а размерът и капацитетът се нулират), което предотвратява двойното освобождаване на паметта. Това е значително по-бързо от пълното копиране, особено за дълги низове.

#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;
}

Конструктор за преместване или оператор за присвояване:

  • Присвоява указател към буфера към целевия обект.
  • Присвоява размер и капацитет към целевия обект.
  • Задава указателя към буфера на изходния обект на nullptr.
  • Задава размера и капацитета на изходния обект на 0.

Това се реализира благодарение на семантиката на преместване (rvalue-ссылки и специални конструктори/оператори).