Fortemente tipado Enumerations em C ++

A programação é toda sobre a legibilidade. É difícil (na verdade, é impossível) para escrever e manter um programa que você não pode ler. Parte de ler uma lista de código-fonte é entender o que os números utilizados no programa representam. A ajuda mais básica que C ++ oferece é o onipresente #definir, como no seguinte exemplo muito citado:

PI #define 3.141592653589793

Esta solução é normal para os valores individuais, embora ele sofre do facto de que o #definir mecanismo não é (estritamente falando) uma parte do C / C ++ desde o pré-processamento é executado antes do compilador. Em resposta a isso, C ++ 2011 introduziu um expressão constante construir:

constexpr long double PI = 3.141592653589793-

o contrastexpr palavra-chave traz constantes na tenda do C ++. este PI tem um tipo real, como variáveis ​​de outro C ++. C ++ pode gerar mensagens de erro com PI que fazem muito mais sentido do que aqueles envolvendo 3,14159.

expressões constantes são muito bem para valores constantes individuais, mas muitas vezes constantes representam conjuntos de coisas, em vez de constantes naturais, como no exemplo a seguir:

#define DC_OR_TERRITORY 0 # definem Alabama 1 # definem ALASKA 2 # define ARKANSAS 3 // ... e assim por diante ...

Presumivelmente estas constantes estão a ser utilizados para identificar os estados, talvez ser usados ​​como um índice para uma série de objectos ou de estado como um valor de um banco de dados em algum lugar.

C ++ há muito tempo tem um mecanismo melhorado para definir estes tipos de constantes - a enumeração:

enum ESTADO {DC_OR_TERRITORY, // recebe 0ALABAMA, // recebe 1ALASKA, // recebe 2ARKANSAS, // ... e assim por diante ...} -

o enum chave introduz uma sequência de constantes chamado uma "contagem". Neste caso, a enumeração carrega o nome ESTADO. Cada elemento desta enumeração é atribuído um valor a partir de 0 e aumentando sequencialmente por uma, assim DC_OR_TERRITORY é definido como 0, ALABAMA é definido como 1, e assim por diante. Você pode substituir esse sequenciamento incremental, utilizando uma instrução de atribuição da seguinte forma:

ESTADO enum {DC, TERRITÓRIO = 0, Alabama, Alaska, // ... e assim por diante ...} -

Esta versão do ESTADO define um elemento DC, que é dado o valor de 0. Em seguida, define um novo elemento TERRITÓRIO, que também é atribuído o valor 0. ALABAMA pega com 1, da mesma maneira que antes.

Na prática, o programador pode usar enumerações de escrever código muito legível como o seguinte:

dupla TaxRate (s ESTADO) {return taxRatesByState [s] -}

O único problema com esta abordagem é que esta enumeração não cria um novo tipo (como se poderia pensar). Na verdade, de acordo com o padrão, ESTADO é apenas outro nome para int - e as constantes ALABAMA, ALASKA, e assim por diante são todos do tipo const int.

O compilador gcc na verdade não fornecer uma enum declarou desta maneira um pouco mais autoridade do que simplesmente chamando-o de uma outra forma de int. Você pode realmente sobrecarregar funções com base em uma enum digitar:

fn void (S State) fn -void (int n) -fn (Alasca) - // invoca fn (ESTADO)

O Standard 2011 permite que o programador para criar um tipo completamente novo usando o enum palavra-chave. Desde os criadores do novo padrão não queria quebrar o código existente, a norma exige a adição de uma palavra-chave extra para definir um tipo de enumeração, como no exemplo a seguir:

ESTADO classe enum {DC, TERRITÓRIO = 0, Alabama, Alaska, // ... e assim por diante ...} -

Uma classe de enumeração é agora um tipo de grande escala como qualquer outra classe definida pelo usuário. O que se segue não é mesmo legal mais por duas razões:

int = s ALASKA-

Em primeiro lugar, a constante ALASKA é apenas definida dentro da ESTADO namespace. Assim, o nome da constante é ESTADO :: ALASKA. Em segundo lugar, o tipo não é int mas ESTADO. Você não pode atribuir um valor de tipo ESTADO para um int.

ESTADO s = ESTADO :: ALASKA-

O programador pode reformular a ESTADO numa int mas ela deve fazê-lo explicitamente conversões -implicit não cortá-la com as classes de enumeração:

int n = (int) ESTADO :: ALASKA-

Este novo tipo enum também pode ser baseada em um dos outros tipos de número de contagem além de apenas int:

classe enum ESTADO: char {DC, // ... o resto da declaração é o mesmo

menu