Costruttori di move e assegnazione di move
Implementi correttamente i costruttori di move e gli operatori di assegnazione di move
Costruttori di move e assegnazione di move è una lezione C++ Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C++ Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C++ Academy include 4 lezioni in totale.
Due membri speciali
Il costruttore di spostamento e l'operatore di assegnazione tramite spostamento consentono alla classe di acquisire le risorse di un'altra istanza senza copiarle.
Firma
Entrambi accettano un riferimento rvalue allo stesso tipo.
class String {
public:
String(String&& other) noexcept; // move ctor
String& operator=(String&& other) noexcept; // move assign
};Implementare un costruttore di spostamento
Acquisisca le risorse della sorgente e la lasci in uno stato vuoto ma valido.
String(String&& other) noexcept
: data_(other.data_), size_(other.size_) {
other.data_ = nullptr;
other.size_ = 0;
}Implementare l'assegnazione tramite spostamento
Tre passaggi: liberi le risorse correnti, acquisisca quelle della sorgente e lasci la sorgente vuota.
String& operator=(String&& other) noexcept {
if (this != &other) {
delete[] data_;
data_ = other.data_;
size_ = other.size_;
other.data_ = nullptr;
other.size_ = 0;
}
return *this;
}Perché noexcept è importante
Contrassegni le operazioni di spostamento con noexcept quando possibile. I container della libreria standard, come std::vector, usano lo spostamento durante il ridimensionamento solo se è noexcept; in caso contrario, ricorrono alle copie per garantire la sicurezza rispetto alle eccezioni.
La regola del cinque
Se ne scrive uno di questi cinque, consideri tutti e cinque:
- Distruttore
- Costruttore di copia
- Assegnazione tramite copia
- Costruttore di spostamento
- Assegnazione tramite spostamento
La regola dello zero
Ancora meglio: non ne scriva nessuno. Conservi i membri come tipi RAII (vector, stringhe, smart pointer). Le implementazioni predefinite generate dal compilatore funzionano correttamente e in modo efficiente.
class Widget {
std::string name_;
std::vector<int> data_;
// No need for destructor, copy, or move — compiler does the right thing
};Quando il compilatore genera le operazioni di move
Il compilatore genera automaticamente i membri di move solo quando:
- Non sono stati dichiarati costruttori di copia, operatori di assegnazione per copia, distruttori o membri di move dall'utente
- Tutti i membri e le classi base sono a loro volta movibili
Operazioni di move predefinite ed eliminate
È possibile richiedere o vietare esplicitamente le operazioni di move generate dal compilatore.
class Widget {
public:
Widget(Widget&&) = default;
Widget& operator=(Widget&&) = default;
// or
Widget(Widget&&) = delete;
};Dopo una move
L'oggetto da cui sono state trasferite le risorse si trova in uno stato valido ma non specificato. È possibile:
- D istruggerlo
- Assegnargli un nuovo valore
- Chiamare qualsiasi operazione che non abbia precondizioni (size(), empty(), clear())
Casi d'uso
La semantica di move velocizza:
- La restituzione di oggetti di grandi dimensioni (quando RVO non viene applicata)
- L'inserimento di oggetti di grandi dimensioni nei contenitori (push_back di rvalue)
- L'implementazione di tipi che gestiscono risorse definiti dall'utente
Verifica rapida
Perché i costruttori di move e gli operatori di assegnazione per move dovrebbero essere contrassegnati con noexcept?
Riepilogo
I costruttori di move e gli operatori di assegnazione per move sottraggono le risorse a un rvalue che sta per essere distrutto. Contrassegnateli con noexcept per velocizzare i contenitori. Seguite la Rule of Five o, meglio ancora, la Rule of Zero componendo tipi RAII standard.
Domande Frequenti
La lezione «Costruttori di move e assegnazione di move» è gratuita?
Sì — il testo completo di «Costruttori di move e assegnazione di move» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C++ Academy, passa a CoddyKit PRO. Il corso C++ Academy include 4 lezioni in totale.
Cosa imparerò in «Costruttori di move e assegnazione di move»?
Implementi correttamente i costruttori di move e gli operatori di assegnazione di move Eserciti C++ Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare C++ Academy?
Non è richiesta alcuna esperienza precedente. C++ Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.
Quanto tempo richiede la lezione «Costruttori di move e assegnazione di move»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione C++ Academy?
Sì. Ogni lezione C++ Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Lvalue e rvalue: la distinzione
- Riferimenti rvalue e sintassi &&
- std::move e std::forward
- Costruttori di move e assegnazione di move