Menu
Coddy logo textTech

Classes Enum e Tipagem Forte

Parte da seção Programação Orientada a Objetos do Journey de C++ da Coddy. Lição 80 de 104.

O C++11 introduziu as classes enum (também chamadas de enumerações com escopo) para resolver as deficiências dos enums tradicionais no estilo C. Elas oferecem uma segurança de tipos mais robusta e evitam o uso acidentalmente incorreto dos valores de enumeração.

Enums tradicionais apresentam problemas: seus valores vazam para o escopo circundante e são convertidos implicitamente em inteiros, levando a bugs sutis:

// Enum tradicional - problemático
enum Color { Red, Green, Blue };
enum TrafficLight { Red, Yellow, Green };  // Erro! Red e Green já definidos

int x = Red;  // Converte implicitamente para int (0)
if (Red == 0) { }  // Compila - comparando enum com int

Classes enum resolvem esses problemas ao delimitar o escopo dos valores e impedir conversões implícitas:

enum class Color { Red, Green, Blue };
enum class TrafficLight { Red, Yellow, Green };  // OK - sem conflito

Color c = Color::Red;      // Deve usar o operador de escopo
// int x = c;              // Erro! Sem conversão implícita
int x = static_cast<int>(c);  // Conversão explícita necessária

// if (c == 0) { }         // Erro! Não é possível comparar com int
if (c == Color::Red) { }   // OK - comparando os mesmos tipos

Você também pode especificar o tipo subjacente para controlar a memória:

enum class Status : uint8_t {
    Inactive = 0,
    Active = 1,
    Pending = 2
};

As classes enum se integram bem aos projetos de POO, tornando o código mais legível e detectando erros de tipo em tempo de compilação, em vez de em tempo de execução.

challenge icon

Desafio

Fácil

Vamos criar um sistema de prioridade de tarefas que usa classes enum para representar diferentes níveis de prioridade e status de tarefas. Isso demonstra como as classes enum fornecem segurança de tipos e evitam os tipos de bugs que ocorrem com enums tradicionais.

Você organizará seu código em três arquivos:

  • TaskTypes.h: Defina suas classes enum para o sistema de tarefas.

    Crie uma classe enum Priority com os valores: Low, Medium, High e Critical. Especifique int como o tipo subjacente, com os valores 1, 2, 3 e 4, respectivamente.

    Crie uma classe enum Status com os valores: Pending, InProgress e Completed.

    Forneça duas funções auxiliares:

    • priorityToString(Priority p): retorna a prioridade como uma string ("Low", "Medium", "High" ou "Critical")
    • statusToString(Status s): retorna o status como uma string ("Pending", "InProgress" ou "Completed")
  • Task.h: Defina uma classe Task que use suas classes enum.

    Sua Task deve armazenar um nome (string), uma Priority e um Status. O construtor deve receber um nome e uma prioridade, com o status tendo como padrão Status::Pending.

    Implemente estes métodos:

    • setStatus(Status s): atualiza o status da tarefa
    • getPriorityValue(): retorna o valor inteiro subjacente da prioridade usando static_cast
    • display(): exibe a tarefa no formato: [name] - Priority: [priority] (Value: [value]) - Status: [status]
  • main.cpp: Leia três entradas:
    1. Nome da tarefa (string)
    2. Nível de prioridade como inteiro (1=Low, 2=Medium, 3=High, 4=Critical)
    3. Status como inteiro (0=Pending, 1=InProgress, 2=Completed)

    Crie uma Task com o nome e a prioridade fornecidos (converta o inteiro para o valor apropriado do enum Priority usando static_cast). Em seguida, defina seu status com base na terceira entrada. Por fim, chame display() para mostrar os detalhes da tarefa.

Por exemplo, com as entradas Fix bug, 3 e 1:

Fix bug - Priority: High (Value: 3) - Status: InProgress

Com as entradas Write docs, 1 e 2:

Write docs - Priority: Low (Value: 1) - Status: Completed

Com as entradas Deploy app, 4 e 0:

Deploy app - Priority: Critical (Value: 4) - Status: Pending

Observe como as classes enum mantêm os valores de prioridade e status completamente separados. Você não pode comparar acidentalmente uma Priority com um Status nem atribuir uma à outra. O static_cast explícito necessário para converter entre inteiros e valores de enum torna clara a intenção do código e evita bugs sutis.

Experimente você mesmo

#include <iostream>
#include <string>
#include "Task.h"

using namespace std;

int main() {
    // Ler entradas
    string taskName;
    int priorityInt;
    int statusInt;
    
    getline(cin, taskName);
    cin >> priorityInt;
    cin >> statusInt;
    
    // TODO: Crie um Task com o nome e a prioridade fornecidos
    // Use static_cast para converter priorityInt para o enum Priority
    
    // TODO: Defina o status da task com base em statusInt
    // Use static_cast para converter statusInt para o enum Status
    
    // TODO: Chame display() para mostrar os detalhes da task
    
    return 0;
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Compilador de C++ online