MySQL Java JavaScript PHP Python HTML-CSS C-sharp C++ Go

Enumerări

Enumerările (enum) reprezintă o altă modalitate de a defini tipuri proprii. Caracteristica lor distinctivă este faptul că ele conțin un set de constante numerice. O enumerare are următoarea formă:

enum class nume_enumerare { constanta_1, constanta_2, ... constanta_N };

După cuvintele cheie enum class urmează numele enumerării, iar apoi, între acolade, sunt enumerate constantele, separate prin virgulă.

Să definim o enumerare simplă:

enum class Day {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday};

În acest caz, enumerarea se numește Day și reprezintă zilele săptămânii. Între acolade sunt toate zilele săptămânii. De fapt, ele reprezintă constante numerice.

Fiecărei constante i se asociază o anumită valoare numerică. Implicit, prima constantă primește valoarea 0, iar următoarele cresc cu câte 1. Astfel, în exemplul de mai sus, Monday va avea valoarea 0, Tuesday – 1 și așa mai departe. Prin urmare, ultima constantă – Sunday va fi egală cu 6.

După crearea enumerării, putem defini o variabilă de acest tip și să îi atribuim una dintre constante:

Day today {Day::Thursday};
// sau
//Day today = Day::Thursday;

În acest caz, se definește variabila today, care este egală cu Day::Thursday, adică a patra constantă din enumerarea Day.

Pentru a afișa valoarea variabilei în consolă, se poate folosi conversia la tipul int:

#include <iostream>
 
enum class Day {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday};
int main()
{
    Day today {Day::Thursday};
    std::cout << "Today: " << static_cast<int>(today) << std::endl;
}

Astfel, în consolă se va afișa Today: 3, deoarece constanta Thursday are valoarea 3.

Putem controla și valorile constantelelor din enumerare. De exemplu, putem seta o valoare de început pentru o constantă, iar celelalte vor crește automat:

enum class Day {Monday = 1, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday};

În acest caz, Tuesday va avea valoarea 2, iar Sunday – 7.

Putem seta valori individuale pentru fiecare constantă sau combina acest mod cu incrementarea automată:

enum class Day {Monday = 2, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday = 1};

Aici, Saturday va avea valoarea 7, iar Sunday – 1.

Este posibil să atribuim aceeași valoare la două constante:

enum class Day {Monday = 1, Mon = 1, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday};

Aici, constantele Monday și Mon au aceeași valoare.

Putem atribui constantelor și valori bazate pe altele deja definite:

enum class Day {Monday = 1, Mon = Monday, Tuesday = Monday + 1, Wednesday, Thursday, Friday, Saturday, Sunday};

Este important de știut că valorile constantelor dintr-o enumerare trebuie să fie valori integrale constante. Totuși, putem alege alt tip întreg, de exemplu char:

enum class Operation: char {Add = '+', Subtract = '-', Multiply = '*'};

Dacă dorim să afișăm aceste valori ca simboluri, trebuie să le convertim în char:

#include <iostream>
 
enum class Operation: char {Add = '+', Subtract='-', Multiply='*'};
int main()
{
    std::cout << "add: " << static_cast<char>(Operation::Add) << std::endl;
    std::cout << "subtracte: " << static_cast<char>(Operation::Subtract) << std::endl;
    std::cout << "multiply: " << static_cast<char>(Operation::Multiply) << std::endl;
}

Utilizarea enumerărilor

Enumerările sunt utile atunci când trebuie să păstrăm un set limitat de stări și, în funcție de starea curentă, să executăm anumite acțiuni. De exemplu:

#include <iostream>
 
enum class Operation {Add, Subtract, Multiply};
 
void calculate(int n1, int n2, Operation op)
{
    switch (op)
    {
        case Operation::Add: 
            std::cout << n1 + n2 << std::endl;
            break;
        case Operation::Subtract:
            std::cout << n1 - n2 << std::endl;
            break;
        case Operation::Multiply:
            std::cout << n1 * n2 << std::endl;
            break;
    }
}
int main()
{
    calculate(10, 6, Operation::Add);           // 16
    calculate(10, 6, Operation::Subtract);      // 4
    calculate(10, 6, Operation::Multiply);      // 60
}

Aici, toate operațiile aritmetice sunt stocate în enumerarea Operation. În funcția calculate, în funcție de valoarea celui de-al treilea parametru – operația aplicată – sunt efectuate anumite acțiuni cu primii doi parametri.

Importarea constantelor din enumerare

În mod implicit, pentru a accesa constantele unei enumerări, trebuie să specificăm numele enumerării, de exemplu Day::Monday. Însă, începând cu standardul C++20, putem importa constantele în contextul curent folosind operatorul using.

using enum Day;

Și apoi putem folosi doar numele constantelor:

#include <iostream>
 
enum class Day {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday};
using enum Day;     // importăm constantele în domeniul de vizibilitate curent
 
int main()
{
    Day today {Thursday};   // folosim doar numele constantei
    // sau
    //Day today = Thursday;
    std::cout << static_cast<int>(today) << std::endl;      // 3
    std::cout << static_cast<int>(Sunday) << std::endl;     // 6
}

De asemenea, putem importa o singură constantă:

using Day::Monday;     // importăm doar Monday
// ...
Day today {Monday};

În acest caz, doar constanta Day::Monday este disponibilă fără prefix. Pentru celelalte constante, trebuie în continuare să folosim numele enumerării.

Deoarece această funcționalitate este disponibilă doar din standardul C++20, la compilare cu g++ sau clang++ trebuie adăugat flagul:

-std=c++20

Enumerări în stil C

Trebuie menționat că anterior în C++ era utilizată o altă formă de enumerări, moștenită din limbajul C, și definită fără cuvântul cheie class:

#include <iostream>
 
enum Day {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday};
 
int main()
{
    Day today = Tuesday;
    std::cout << today << std::endl;    // 1 
}

Astfel de enumerări se mai numesc unscoped (neîncadrate într-un domeniu). Aceste enumerări pot fi întâlnite în programele mai vechi. Totuși, pentru că pot duce mai ușor la erori, această formă este folosită tot mai rar în prezent.