Tipo di enumerazione in C++

Jinku Hu 12 ottobre 2023
  1. Enumerazioni senza ambito in C++
  2. Enumerazioni con ambito in C++
Tipo di enumerazione in C++

Questo articolo mostrerà come usare il tipo di enumerazione in C++.

Enumerazioni senza ambito in C++

Le enumerazioni fanno parte del linguaggio C da un po’ di tempo. Il C++ ha anche implementato lo stesso concetto con alcune funzionalità aggiuntive. In genere, l’enumerazione è il meccanismo per denominare gli interi costanti. Il programmatore definisce i nomi degli enumeratori. I valori integrali possono essere specificati esplicitamente o dedotti dalla posizione del nome dato.

Le enumerazioni vengono determinate utilizzando la parola chiave enum e possono facoltativamente definire un nome per il tipo (ad es. Color nel seguente frammento di codice). Si noti che le costanti di enumerazione C++ hanno tipi integrali definiti dall’implementazione. Quindi, se i valori dati richiedono uno spazio maggiore di int, il tipo integrale corrispondente viene scelto come tipo sottostante. Il tipo può anche essere specificato in modo esplicito dall’utente dopo il nome dell’enumerazione e deve essere separato con due punti (mostrato nel quarto frammento di codice in questo articolo).

Nell’esempio seguente, definiamo un’enumerazione denominata Color e specifichiamo i sei nomi di colore come costanti enumerate. Poiché a nessuna di queste costanti è assegnato il valore esplicito, i valori integrali vengono dedotti con le loro posizioni a partire da zero. Questo codice implementa una funzione di conversione da colore a stringa, che è limitata ai valori indicati. Anche la variabile Color è un’enumerazione senza ambito; ciò significa che i suoi enumeratori (costanti) sono accessibili dallo stesso ambito dell’enumerazione stessa.

#include <iostream>

using std::cout;
using std::endl;
using std::string;

enum Color { RED, GREEN, BLUE, CYAN, MAGENTA, YELLOW };

string ColorToString(Color c) {
  switch (c) {
    case RED:
      return "Red";
    case BLUE:
      return "Blue";
    case GREEN:
      return "Green";
    case CYAN:
      return "Cyan";
    case MAGENTA:
      return "Magenta";
    case YELLOW:
      return "Yellow";
    default:
      return "NAN";
  }
}

int main() {
  Color col1 = RED;

  cout << "the given color is " << ColorToString(col1) << endl;

  return EXIT_SUCCESS;
}

Produzione:

the given color is Red

In alternativa, possiamo definire un’enumerazione (es. WeekDay) dove ogni enumeratore ha il valore integrale esplicitamente assegnato. È possibile utilizzare questa funzionalità per implementare una struttura flessibile che può essere modificata in base a diverse convenzioni di data. I valori espliciti e posizionali possono essere combinati nello stesso oggetto di enumerazione, se necessario.

#include <iostream>

using std::cout;
using std::endl;

enum WeekDay { MON = 1, TUE = 2, WED = 3, THU = 4, FRI = 5, SAT = 6, SUN = 7 };

int main() {
  auto today = SAT;
  cout << "today is " << today << "th day" << endl;

  return EXIT_SUCCESS;
}

Produzione:

today is 6th day

Enumerazioni con ambito in C++

Un’altra caratteristica utile delle enumerazioni è quella di avere un ambito; pertanto, si chiama enumerazioni con ambito. Quest’ultimo può essere dichiarato utilizzando le parole chiave enum class o enum struct. Le enumerazioni con ambito seguono le solite convenzioni di ambito e non sono accessibili al di fuori dell’ambito dell’enumerazione. Tra i lati positivi, le enumerazioni con ambito globale non genereranno conflitti di nomi come potrebbero fare le enumerazioni senza ambito.

L’esempio di codice successivo definisce WeekDay dell’esempio precedente come enumerazione con ambito. Si noti che le enumerazioni senza ambito possono essere stampate utilizzando la funzione cout come qualsiasi altra variabile, ma quella con ambito deve essere convertita al valore integrale corrispondente.

#include <iostream>

using std::cout;
using std::endl;

enum class WeekDay {
  MON = -1,
  TUE = 2,
  WED = 3,
  THU = 4,
  FRI = 5,
  SAT = 6,
  SUN = 7
};

int main() {
  auto today = WeekDay::MON;
  cout << "today is " << static_cast<unsigned>(today) << "th day" << endl;

  return EXIT_SUCCESS;
}

Produzione:

today is 6th day

Le enumerazioni con ambito devono avere un nome, a differenza di quelle senza ambito. D’altra parte, l’enumerazione con scope non ha un tipo integrale sottostante predefinito. Tenere presente che la conversione del tipo sottostante può causare overflow quando viene eseguito il cast degli enumeratori su tipi diversi.

#include <iostream>

using std::cout;
using std::endl;

enum class WeekDay : int {
  MON = -1,
  TUE = 2,
  WED = 3,
  THU = 4,
  FRI = 5,
  SAT = 6,
  SUN = 7
};

int main() {
  auto today = WeekDay::MON;
  cout << "today is " << static_cast<unsigned>(today) << "th day" << endl;

  return EXIT_SUCCESS;
}

Produzione:

today is 4294967295th day
Autore: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Articolo correlato - C++ Enum