Konstruktory przenoszące i przenoszące operatory przypisania
Poprawnie implementuj konstruktory przenoszące i przenoszące operatory przypisania
Konstruktory przenoszące i przenoszące operatory przypisania to bezpłatna lekcja C++ Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej C++ Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs C++ Academy zawiera 4 lekcji w sumie.
Dwaj specjalni członkowie
konstruktor przenoszący i operator przypisania przenoszącego pozwalają klasie przejąć zasoby innej instancji bez ich kopiowania.
Sygnatura
Oba przyjmują referencję rvalue do tego samego typu.
class String {
public:
String(String&& other) noexcept; // move ctor
String& operator=(String&& other) noexcept; // move assign
};Implementowanie konstruktora przenoszącego
Należy przejąć zasoby źródła i pozostawić je w prawidłowym, pustym stanie.
String(String&& other) noexcept
: data_(other.data_), size_(other.size_) {
other.data_ = nullptr;
other.size_ = 0;
}Implementowanie operatora przypisania przenoszącego
Trzy kroki: zwolnić bieżące zasoby, przejąć zasoby źródła i pozostawić źródło puste.
String& operator=(String&& other) noexcept {
if (this != &other) {
delete[] data_;
data_ = other.data_;
size_ = other.size_;
other.data_ = nullptr;
other.size_ = 0;
}
return *this;
}Dlaczego noexcept ma znaczenie
Operacje przenoszenia należy oznaczać jako noexcept, gdy tylko jest to możliwe. Kontenery standardowe, takie jak std::vector, używają przenoszenia podczas zmiany rozmiaru tylko wtedy, gdy jest ono oznaczone jako noexcept; w przeciwnym razie, aby zapewnić bezpieczeństwo wyjątków, korzystają z kopiowania.
Reguła pięciu
Jeśli napiszą Państwo którykolwiek z tych pięciu elementów, należy rozważyć wszystkie pięć:
- destruktor
- konstruktor kopiujący
- operator przypisania kopiującego
- konstruktor przenoszący
- operator przypisania przenoszącego
Reguła zera
Jeszcze lepiej — nie pisać żadnego z nich. Należy przechowywać składowe jako typy RAII (wektory, napisy, inteligentne wskaźniki). Domyślne implementacje wygenerowane przez kompilator będą działać poprawnie i wydajnie.
class Widget {
std::string name_;
std::vector<int> data_;
// No need for destructor, copy, or move — compiler does the right thing
};Kiedy kompilator generuje operacje przenoszenia
Kompilator generuje domyślne funkcje przenoszące tylko wtedy, gdy:
- użytkownik nie zadeklarował konstruktora kopiującego, operatora przypisania kopiującego, destruktora ani funkcji przenoszących
- wszystkie składowe i klasy bazowe można samodzielnie przenosić
Domyślne i usunięte operacje przenoszenia
Można jawnie zażądać wygenerowania przez kompilator funkcji przenoszących lub zabronić ich generowania.
class Widget {
public:
Widget(Widget&&) = default;
Widget& operator=(Widget&&) = default;
// or
Widget(Widget&&) = delete;
};Po przeniesieniu
Obiekt, z którego przeniesiono dane, znajduje się w stanie poprawnym, lecz nieokreślonym. Można:
- zniszczyć go
- przypisać mu nową wartość
- wywołać dowolną operację, która nie ma warunku wstępnego (size(), empty(), clear())
Przypadki użycia
Semantyka przenoszenia przyspiesza:
- zwracanie dużych obiektów (gdy RVO nie zadziała)
- umieszczanie dużych obiektów w kontenerach (push_back dla r-wartości)
- implementowanie własnych typów zarządzających zasobami
Szybkie sprawdzenie
Dlaczego konstruktory przenoszące i operatory przypisania przenoszącego powinny być oznaczane jako noexcept?
Podsumowanie
Konstruktory przenoszące i operatory przypisania przenoszącego przejmują zasoby od r-wartości, która wkrótce przestanie istnieć. Należy oznaczać je jako noexcept, aby przyspieszyć działanie kontenerów. Należy stosować regułę pięciu — a jeszcze lepiej regułę zera, składając typy ze standardowych typów RAII.
Często zadawane pytania
Czy lekcja „Konstruktory przenoszące i przenoszące operatory przypisania” jest bezpłatna?
Tak — pełny tekst „Konstruktory przenoszące i przenoszące operatory przypisania” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu C++ Academy, przejdź na CoddyKit PRO. Kurs C++ Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Konstruktory przenoszące i przenoszące operatory przypisania”?
Poprawnie implementuj konstruktory przenoszące i przenoszące operatory przypisania Ćwiczysz C++ Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć C++ Academy?
Nie wymagamy żadnego doświadczenia. C++ Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.
Ile czasu zajmuje lekcja „Konstruktory przenoszące i przenoszące operatory przypisania”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji C++ Academy?
Tak. Każda lekcja C++ Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Lvalue a rvalue — różnica
- Referencje rvalue i składnia &&
- std::move i std::forward
- Konstruktory przenoszące i przenoszące operatory przypisania