0Pricing
C++ Academy · Lezione

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

  1. Lvalue e rvalue: la distinzione
  2. Riferimenti rvalue e sintassi &&
  3. std::move e std::forward
  4. Costruttori di move e assegnazione di move
← Torna a C++ Academy