Зачем нужен enum class

      Комментарии к записи Зачем нужен enum class отключены

Помечено: , ,

В этой теме 0 ответов, 1 участник, последнее обновление  Васильев Владимир Сергеевич 2 мес., 3 нед. назад.

  • Автор
    Сообщения
  • #3557

    Перечисления (enum) используются в C++-коде достаточно часто. Оно и понятно: возможность ассоциировать некое значение с понятным именем в ряде случаев довольно ценна. Однако с использованием перечислений сопряжены некоторые (хорошо известные) проблемы. Нет, они не всегда приводят к ошибкам, и если всегда быть внимательным, то и вспоминать о них, об этих проблемах, не придётся. Однако программисты не всегда внимательны, поэтому нововведение в C++11, называемое классы-перечисления (enum class), является действительно ценным.

    Предназначение класса-перечисления именно в том, чтобы избавиться от проблем классического enum. Мы будем вспоминать эти проблемы последовательно, и тут же анализировать то, что предлагает C++11.

    Итак:

    enum error {
      file_not_found
      , cannot_open
      , invalid_coding
    };
    int main() {
      error e = file_not_found;
    }

    Как видим, конкретное значение file_not_found принадлежит внешнему по отношению к enum пространству имён. Значит, если enum error определён в глобальном пространстве имён, то и его значения будут глобальны. Это не очень хорошо, хотя бы только потому, что возможен конфликт между именами в разных enum:

    enum error {
      file_not_found
      , cannot_open
      , invalid_coding
    };
    // Где-то в другом месте...
    enum error2 {
      file_not_found
      , cannot_open
      , invalid_coding
    };

    Компилятор ругнётся, и правильно сделает:

    error: conflicting declaration ‘file_not_found’ error: ‘file_not_found’ has a previous declaration as ‘error file_not_found’

    Класс-перечисление решает эту проблему.

    enum class error {
      // Мы просто добавили слово class после enum, только и всего.
      file_not_found
      , cannot_open
      , invalid_coding
    };
    int main() {
      error e = error::file_not_found;
    }

    Как видим, значение file_not_found теперь принадлежит области видимости error, и это гораздо логичнее. Понятно, что конфликта имён уже нет:

    int main() {
      error e = error::file_not_found;
      error2 e2 = error2::file_not_found;
    }

    Подобное решение делает код безопаснее и яснее для восприятия.

Для ответа в этой теме необходимо авторизоваться.