0Pricing
C++ Academy · Aula

Uniões e seus riscos

Compartilhe memória entre tipos

Uniões e seus riscos é uma aula grátis de C++ Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de C++ Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de C++ Academy inclui 4 aulas no total.

O que é uma união?

Uma union permite que vários membros compartilhem a mesma memória. Apenas um membro é válido por vez, e a união tem o tamanho do seu maior membro.

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

Tamanho de uma união

Como os membros se sobrepõem, o sizeof de uma união é igual ao tamanho do seu maior membro (mais qualquer preenchimento de alinhamento), e não à soma dos tamanhos.

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

Escrever em um membro e ler outro

Escrever em um membro e ler outro é o risco central. Os bits são reinterpretados, o que geralmente resulta em um comportamento indefinido ou surpreendente.

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

Apenas um membro ativo

O membro no qual você escreveu por último é o único que pode ler com segurança. Controle por conta própria qual membro está "ativo"; a união não se lembra disso.

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

O padrão de união marcada

Para usar uniões com segurança, associe-as a um marcador (uma enumeração) que registre o membro ativo. Este é o precursor manual de 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";
}

Lendo o membro correto

Sempre verifique o marcador antes de ler. Ler o membro errado produz valores sem sentido.

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

Membros não triviais

Colocar em uma união um membro com construtor ou destrutor (como std::string) exige construção e destruição manuais. Isso é propenso a erros e é mais um motivo para preferir std::variant.

Uniões anônimas

Uma união anônima não tem nome; seus membros são acessados diretamente. Ela é útil dentro de uma estrutura, mas a mesma regra do membro ativo se aplica.

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

Por que as uniões são arriscadas

Resumo dos perigos:

  • Nenhuma informação sobre qual membro está ativo.
  • Ler um membro inativo resulta em comportamento indefinido.
  • Tipos não triviais precisam de gerenciamento manual do tempo de vida.

Quando as uniões ainda são úteis

As uniões continuam sendo úteis em trabalhos de baixo nível: para reinterpretar bytes, economizar memória em código embarcado com recursos limitados ou corresponder a um esquema binário fixo. Para dados cotidianos que podem ser de "um entre vários tipos", prefira a alternativa mais segura.

Em direção a std::variant

std::variant é uma união segura quanto aos tipos que controla o tipo ativo para você e lança uma exceção se você acessar o tipo errado. O restante deste curso explora esse recurso.

Verificação rápida

Verifique sua compreensão sobre uniões.

Recapitulação

Você aprendeu sobre uniões:

  • Todos os membros compartilham um único bloco de memória.
  • Apenas o membro escrito por último é válido para leitura.
  • Use um marcador (enumeração) para controlar o membro ativo.
  • Prefira std::variant por segurança no C++ moderno.

Perguntas Frequentes

A aula “Uniões e seus riscos” é grátis?

Sim — o texto completo de “Uniões e seus riscos” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de C++ Academy, atualize para CoddyKit PRO. O curso de C++ Academy inclui 4 aulas no total.

O que vou aprender em “Uniões e seus riscos”?

Compartilhe memória entre tipos Você pratica C++ Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar C++ Academy?

Nenhuma experiência prévia é necessária. C++ Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.

Quanto tempo leva a aula “Uniões e seus riscos”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de C++ Academy?

Sim. Cada aula de C++ Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. enum class com escopo
  2. Uniões e seus riscos
  3. std::variant
  4. std::visit
← Voltar para C++ Academy