C++ Academy · Lezione

Union e relativi rischi

Condividere la memoria tra i tipi

Lezione 2 di 413 passaggi

Union e relativi rischi è una lezione C++ Academy gratuita su CoddyKit. Questa è la lezione 2 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.

Che cos'è un'unione

Una union consente a più membri di condividere la stessa memoria. È valido un solo membro alla volta e l'unione ha dimensioni pari a quelle del membro più grande.

#include <iostream>
union Number {
    int i;
    float f;
};
int main() {
    Number n;
    n.i = 42;
    std::cout << n.i << "\n";
}

Dimensioni di un'unione

Poiché i membri si sovrappongono, sizeof di un'unione è uguale alle dimensioni del membro più grande (più l'eventuale spazio di allineamento), non alla somma delle dimensioni.

#include <iostream>
union Mix { char c; int i; double d; };
int main() {
    std::cout << sizeof(Mix) << "\n"; // size of double (often 8)
}

Scrivere un membro e leggerne un altro

Scrivere in un membro e leggerne un altro è il rischio principale. I bit vengono reinterpretati, con risultati generalmente non definiti o sorprendenti.

#include <iostream>
union Bits { int i; float f; };
int main() {
    Bits b;
    b.f = 1.0f;
    std::cout << b.i << "\n"; // reads float bits as int
}

Un solo membro attivo

Il membro scritto per ultimo è l'unico che può essere letto in sicurezza. Spetta a Lei tenere traccia del membro "attivo": la union non lo ricorda.

#include <iostream>
union Value { int i; double d; };
int main() {
    Value v;
    v.d = 3.14;        // d is active
    std::cout << v.d << "\n";
}

Il modello della union con tag

Per usare le union in sicurezza, le si abbina a un tag (un enum) che registra il membro attivo. Questo è l'antenato manuale di std::variant.

#include <iostream>
struct Tagged {
    enum { Int, Double } tag;
    union { int i; double d; };
};
int main() {
    Tagged t; t.tag = Tagged::Int; t.i = 7;
    if (t.tag == Tagged::Int) std::cout << t.i << "\n";
}

Leggere il membro corretto

Prima di leggere, verifichi sempre il tag. La lettura del membro sbagliato produce valori spazzatura.

#include <iostream>
struct Tagged {
    enum { Int, Double } tag;
    union { int i; double d; };
};
void print(const Tagged& t) {
    if (t.tag == Tagged::Int) std::cout << "int " << t.i << "\n";
    else std::cout << "double " << t.d << "\n";
}
int main() { Tagged t{Tagged::Double}; t.d = 2.5; print(t); }

Membri non banali

Inserire in una union un membro con un costruttore o un distruttore, come std::string, richiede la costruzione e la distruzione manuali. È soggetto a errori, un altro motivo per preferire std::variant.

Union anonime

Una union anonima non ha nome; i suoi membri sono accessibili direttamente. È utile all'interno di una struct, ma si applica la stessa regola del membro attivo.

#include <iostream>
struct Packet {
    int kind;
    union { int code; char letter; };
};
int main() {
    Packet p; p.kind = 1; p.code = 99;
    std::cout << p.code << "\n";
}

Perché le union sono rischiose

Riepilogo dei rischi:

  • Non conservano informazioni sul membro attivo.
  • La lettura di un membro inattivo comporta un comportamento non definito.
  • I tipi non banali richiedono la gestione manuale del ciclo di vita.

Quando le union sono ancora utili

Le union restano utili per operazioni a basso livello: reinterpretare byte, risparmiare memoria in codice embedded con risorse limitate o rispettare un layout binario fisso. Per i dati quotidiani che rappresentano "uno tra diversi tipi", preferisca l'alternativa più sicura.

Verso std::variant

std::variant è una union con sicurezza dei tipi che tiene traccia del tipo attivo al posto Suo e genera un'eccezione se si accede a quello sbagliato. Il resto del corso la esplora in dettaglio.

Verifica rapida

Verifichi la Sua comprensione delle union.

Riepilogo

Ha imparato a conoscere le union:

  • Tutti i membri condividono lo stesso blocco di memoria.
  • Solo il membro scritto per ultimo può essere letto validamente.
  • Utilizzi un tag (enum) per tenere traccia del membro attivo.
  • In C++ moderno, preferisca std::variant per una maggiore sicurezza.
Gratis per iniziare

Impara C++ con un tutor IA — gratis

Scrivi ed esegui vero codice nel tuo browser, ricevi aiuto istantaneo da un tutor IA disponibile 24/7, e riprendi da dove hai lasciato sul web o nell'app.

Corsi
51
Lezioni
203

Domande Frequenti

La lezione «Union e relativi rischi» è gratuita?

Sì — il testo completo di «Union e relativi rischi» è 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 «Union e relativi rischi»?

Condividere la memoria tra i tipi 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 2 di 4.

Quanto tempo richiede la lezione «Union e relativi rischi»?

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. Classe enum con ambito
  2. Union e relativi rischi
  3. std::variant
  4. std::visit
← Torna a C++ Academy