Enum — Присваивание enum по ссылке или без. c++


Содержание

Enum — Присваивание enum по ссылке или без. c++

Сообщения: 1285
Благодарности: 142

Сообщения: 1180
Благодарности: 279

Конфигурация компьютера
Материнская плата: MSI P55-CD53
HDD: 3 x 320Gb Seagate Barracuda 7200.10 ST3320620AS (Кэш: 16Mb) (SATAII) + 400Gb Samsung + 1Tb Western Digital
Звук: Интегрированная
CD/DVD: ASUS DVD-RW (Model No.: DRW-1608P3S)
ОС: Windows 7 Ultimate x64 (от m0nkrus)
vartest = (COLOR) 4; »

Это сообщение посчитали полезным следующие участники:

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.

Сообщения: 1285
Благодарности: 142

Конфигурация компьютера
Материнская плата: MSI P55-CD53
HDD: 3 x 320Gb Seagate Barracuda 7200.10 ST3320620AS (Кэш: 16Mb) (SATAII) + 400Gb Samsung + 1Tb Western Digital
Звук: Интегрированная
CD/DVD: ASUS DVD-RW (Model No.: DRW-1608P3S)
ОС: Windows 7 Ultimate x64 (от m0nkrus)
Когда используются сишные, а не плюсплюсные преобразования типов, используются сишные правила. А они это позволяют. »
Чтобы такого не было, нужно в настройках компилятора поставить галочку, запрещающую преобразование int в enum »

Мне хотелось бы сохранить возможность преобразования int в enum.

P.S: Неужели придется писать свой код, контролирующий корректность значения int перед его преобразованием в enum? Хотелось бы этого избежать.
P.S.S: По ходу изучения работы с перечислениями я столкнулся с еще одной непоняткой. Проблема в том, что компилятор не дает мне при создании нескольких разных типов-перечислений использовать в качестве одного из их возможных значений одноименную константу. Сразу скажу, что технически я понимаю почему это происходит. Мне не понятно: почему так сделали? Зачем сделали возможные значения перечислений доступными коду как обычные константы?

——-
Здесь вместо «Спасибо» принято щелкать на «Полезное сообщение» у тех постов, которые вам помогли, или показались полезными.

Перечисления (C++) Enumerations (C++)

Перечисление — это пользовательский тип, состоящий из набора целочисленных констант, называемых перечислителями. An enumeration is a user-defined type that consists of a set of named integral constants that are known as enumerators.

В этой статье рассматриваются языка C++ стандарта ISO перечисления типа и области (или со строгой типизацией) класс перечисления тип, который впервые введен в C ++ 11. This article covers the ISO Standard C++ Language enum type and the scoped (or strongly-typed) enum class type which is introduced in C++11. Сведения о открытый класс перечисления или класс закрытого перечисления типы в C++выполняет и C++/CX, см. в разделе класс перечисления. For information about the public enum class or private enum class types in C++/CLI and C++/CX, see enum class.

Синтаксис Syntax

Параметры Parameters


identifier identifier
Имя типа, присваиваемое перечислению. The type name given to the enumeration.

type type
Базовый тип перечислителей; все перечислители имеют один базовый тип. The underlying type of the enumerators; all enumerators have the same underlying type. Может быть любым целочисленным типом. May be any integral type.

Enum-list enum-list
Разделенный запятыми список перечислителей в перечислении. Comma-separated list of the enumerators in the enumeration. Каждый перечислитель или имя переменной в области должны быть уникальными. Every enumerator or variable name in the scope must be unique. Однако значения могут повторяться. However, the values can be duplicated. В неограниченном перечислении видимости является окружающая область; в ограниченном перечислении областью видимости является перечисления списка сам. In a unscoped enum, the scope is the surrounding scope; in a scoped enum, the scope is the enum-list itself. В ограниченном перечислении областью, список может быть пустым в силе, который определяет новый целочисленный тип. In a scoped enum, the list may be empty which in effect defines a new integral type.

class class
Используя это ключевое слово в объявлении, указать, что перечисление ограничено и идентификатор должно быть указано. By using this keyword in the declaration, you specify the enum is scoped, and an identifier must be provided. Можно также использовать структуры ключевое слово вместо класс, как они семантически эквивалентны, в этом контексте. You can also use the struct keyword in place of class, as they are semantically equivalent in this context.

Область перечислителя Enumerator scope

Перечисление предоставляет контекст для описания диапазона значений, которые представлены в виде именованных констант и также называются перечислителями. An enumeration provides context to describe a range of values which are represented as named constants and are also called enumerators. В первоначальных типах перечислений C и C++ перечислители с неполным имеем являются видимыми внутри области видимости, в которой объявлено перечисление. In the original C and C++ enum types, the unqualified enumerators are visible throughout the scope in which the enum is declared. В ограниченных перечислениях имя перечислителя должно уточняться именем типа перечисления. In scoped enums, the enumerator name must be qualified by the enum type name. В следующем примере демонстрируется основное различие между двумя видами перечислений. The following example demonstrates this basic difference between the two kinds of enums:

Каждому имени в перечислении присваивается целочисленное значение, которое соответствует определенному месту в порядке значений в перечислении. Every name in an enumeration is assigned an integral value that corresponds to its place in the order of the values in the enumeration. По умолчанию первому значению присваивается 0, следующему — 1 и т. д., но можно задать значение перечислителя явным образом, как показано ниже: By default, the first value is assigned 0, the next one is assigned 1, and so on, but you can explicitly set the value of an enumerator, as shown here:

Перечислителю Diamonds присваивается значение 1 . The enumerator Diamonds is assigned the value 1 . Если последующим перечислителям не присваиваются явные значения, они получают значение предыдущего перечислителя плюс один. Subsequent enumerators, if they are not given an explicit value, receive the value of the previous enumerator plus one. В предыдущем примере Hearts имел бы значение 2, Clubs — значение 3 и т.д. In the previous example, Hearts would have the value 2, Clubs would have 3, and so on.

Каждый перечислитель обрабатывается как константа и должен иметь уникальное имя в области где перечисления определяется (для неограниченных перечислений) или в перечисления сам (для ограниченных перечислений). Every enumerator is treated as a constant and must have a unique name within the scope where the enum is defined (for unscoped enums) or within the enum itself (for scoped enums). Значения, задаваемые имена, могут быть неуникальными. The values given to the names do not have to be unique. Например, для следующего объявления неограниченного перечисления Suit : For example, if the declaration of a unscoped enum Suit is this:

значения Diamonds , Hearts , Clubs и Spades равны 5, 6, 4 и 5 соответственно. Then the values of Diamonds , Hearts , Clubs , and Spades are 5, 6, 4, and 5, respectively. Обратите внимание, что значение 5 используется несколько раз; это допускается, независимо от намерений разработчика. Notice that 5 is used more than once; this is allowed even though it may not be intended. Такие же правила распространяются на ограниченные перечисления. These rules are the same for scoped enums.

Приведение правил Casting rules

Неограниченные перечисления-константы могут неявно преобразовываться к int, но int не может быть неявно преобразован в значение перечисления. Unscoped enum constants can be implicitly converted to int, but an int is never implicitly convertible to an enum value. В следующем примере показано, что пройдет при попытке присвоить переменной hand значение, не относящееся к типу Suit : The following example shows what happens if you try to assign hand a value that is not a Suit :

Необходимо приведение для преобразования int на ограниченный или неограниченный перечислитель. A cast is required to convert an int to a scoped or unscoped enumerator. Однако неограниченный перечислитель можно преобразовать в целочисленное значение без приведения. However, you can promote a unscoped enumerator to an integer value without a cast.

Использование подобных неявных преобразований может приводить к непредвиденным побочным эффектам. Using implicit conversions in this way can lead to unintended side-effects. Чтобы избежать ошибок программирования, связанных с неограниченными перечислениями, значения ограниченных перечислений являются строго типизированными. To help eliminate programming errors associated with unscoped enums, scoped enum values are strongly typed. Ограниченные перечислители должны уточняться именем типа перечисления (идентификатором); они не могут быть неявно преобразованы, как показано в следующем примере: Scoped enumerators must be qualified by the enum type name (identifier) and cannot be implicitly converted, as shown in the following example:

Обратите внимание, что в строке hand = account_num; по-прежнему содержится ошибка, которая происходит при использовании неограниченных перечислений, как показано выше. Notice that the line hand = account_num; still causes the error that occurs with unscoped enums, as shown earlier. Эта ошибка устраняется с помощью явного приведения. It is allowed with an explicit cast. Однако при использовании ограниченных перечислений попытка преобразования в следующем операторе — account_num = Suit::Hearts; — больше не будет разрешена без явного приведения. However, with scoped enums, the attempted conversion in the next statement, account_num = Suit::Hearts; , is no longer allowed without an explicit cast.

Перечисления атрибутом не перечислителей Enums with no enumerators

Visual Studio 2020 версии 15.3 и более поздние версии (состав /std: c ++ 17): Определив перечисления (обычный или областью действия) с помощью явного базового типа и не перечислители, фактически можно ввести новый целочисленный тип, который не имеет неявного преобразования к любому другому типу. Visual Studio 2020 version 15.3 and later (available with /std:c++17): By defining an enum (regular or scoped) with an explicit underlying type and no enumerators, you can in effect introduce a new integral type that has no implicit conversion to any other type. С помощью этого типа вместо встроенных базового типа, можно исключить вероятность ошибкам из-за случайных неявные преобразования. By using this type instead of its built-in underlying type, you can eliminate the potential for subtle errors caused by inadvertent implicit conversions.

Новый тип является точную копию базового типа и, следовательно, соглашение о вызове, это означает, что он может использоваться через ABI без снижения производительности. The new type is an exact copy of the underlying type, and therefore has the same calling convention, which means it can be used across ABIs without any performance penalty. Преобразование не требуется, когда переменные типа инициализируются с помощью инициализации прямого списка. No cast is required when variables of the type are initialized by using direct-list initialization. В следующем примере показано, как для инициализации перечисления атрибутом не перечислители в различных контекстах: The following example shows how to initialize enums with no enumerators in various contexts:

Присвоение значений после определения перечисления

1 Xaymar [2013-01-06 16:38:00]

Я новичок в C++ и особенно C++ 11, так как теперь я должен использовать его, появилось несколько вопросов о «enum» и «enum class»:


Можно ли присвоить значения после объявления перечисления?

Можно ли присвоить значения числу? (например: Myenum :: 0 = 2)

Как класс enum работает при использовании структуры или класса в качестве базового типа?

Будут ли записи в перечислении действительными экземплярами struct/class?

Я нашел эти ссылки, когда искал тему:

Который, как вы можете видеть, оставил несколько вопросов.

c++ enums enum-class assign

2 ответа

4 Решение Nawaz [2013-01-06 16:43:00]

Нет. Вы не можете это сделать.

Однако вы можете указать определение enum после его объявления как:

Можно ли присвоить значения числу?

Нет. Это не имеет смысла. Число уже имеет значение. Он постоянный.

Пожалуйста, получите вводную книгу по программированию в C++. Вот несколько рекомендаций:

Прежде всего, вы не можете присваивать значение в C++. Недопустимо следующее:

И по той же причине вы также не можете присвоить значение перечисления.

Кроме того, вы не можете даже использовать значения перечисления после его объявления (т. auto x = enum_name::name; Вы не можете писать auto x = enum_name::name; ), только после определения. Вы можете использовать только имя перечисления.

Можно ли присвоить значения числу?

Я не уверен, что это должно означать, но помимо того, что Ive сказал, прежде чем этот синтаксис является незаконным в любом случае. То есть вы не можете получить доступ ко второму значению перечисления, написав имя enum_name::1 .

Как класс enum работает при использовании структуры или класса в качестве базового типа?

Вы не можете использовать пользовательские типы как базовые типы, а только встроенные интегральные типы.


Перечисления в C++ (c++ enum types)

категория
C++
дата 15.05.2009
автор analizer
голосов 23

Мнение автора может не совпадать с его точкой зрения
(с) спёрто из ЖЖ

Рекомендуемая литература:

Введение в перечисления

Как известно, перечисления — это тип который может содержать значения указанные программистом. Целочисленные именованные константы могут быть определены как члены перечисления. Например:

определяет три целочисленные константы и присваивает им значения. По умолчанию, значения присваиваются по порядку начиная с нуля, т.е. RED == 0 , GREEN == 1 и BLUE == 2 . Перечисление также может быть именованным: Каждое перечисление — это отдельный тип, и тип каждого члена перечисления — это само перечисление. Например RED имеет тип color . Объявление типа переменной как color , вместо обычного unsigned , может подсказать и программисту и компилятору о том как эта переменная должна быть использована. Например:

В этом случае компилятор может выдать предупреждение о том, что обрабатываются только два значения color из трёх возможных.

Таким образом перечисления это:

— Создание именованных констант с автоматическим увеличением значения константы

— Предупреждения о возможных ошибках со стороны компилятора

Основные проблемы при использовании enum

На самом деле всё что выше — общие слова, которые нужны только для того чтобы те кто забрёл сюда по ошибке, хотя бы что-то из этой статьи вынесли. А мы сейчас поговорим о сложностях и хитростях с которыми приходится сталкиваться каждому кто более-менее юзает перечисления в нормальном девелопменте. Итак, с чем приходится сталкиваться:

1. Отображение значения перечисления в строку которая совпадает с именем члена перечисления, т.е. что-либо что для enum_map[RED] вернёт «RED» .

2. Итерация по членам перечисления и контроль выхода за границы. Т.е. сколько бы вы не добавляли новых элементов в перечисление, у вас всегда есть константа которая ровно на единицу больше последнего члена последовательности.

3. (Тем, кто не прошёл тест по шаблонам, можно не читать) Отображение run-time целочисленной переменной в compile-time переменную или тип (указатель на функцию с определённым значением параметра шаблона etc.).

Разберём вышеозначенные задачи в деталях.

Отображение членов перечисления в строки

Оправданий для того чтобы использовать такой код может быть только два:

  • Если стоит статическая проверка на равенство количества членов перечисления и количества элементов в массиве строк (о статических проверках можете прочитать у Александреску или дождаться моей следующей статьи, которая как раз будет написана по этой теме). Оправдание довольно слабое.
  • Если строки могут не совпадать с названиями членов перечисления (редкий, на самом деле, случай). Т.е. что-то типа такого: const char* const strs[]=<"Red as an egypt rose","Green peace","Blue Screen of Death">; .

Решение:


Уберите от экранов детей!
присутствуют сцены аморального и порнографического характера

Превратим то изящное перечисление, которое у нас было:

вот в этого монстра Франкенштейна:

color.h

Выглядит пугающе, но на самом деле мы просто добавили возможность переопределить каждый элемент конструкции enum :

enum_helper_pre.h

Думаю понятно что в конце для всех этих макросов нужно сделать #undef :

enum_helper_post.h

Теперь если вам нужно заполнить некий массив строковыми представлениями членов перечисления, то выглядеть это будет так:

Output

Вуаля! Вот оно — три строчки кода и вы для любого перечисления, оформленного по нашим правилам, получаете массив из строковых представлений членов перечисления, независимо от количества членов перечисления. Любой человек который будет дебажить код по трейсам, в которых вместо безликих чисел будут стоять названия элементов, скажет вам огромное спасибо.

Итерация по членам перечисления и контроль выхода за границы

Опытный глаз заметит, что пример выше получился немного хромой, потому что перечислениям в крупных проектах свойственно расти с течением времени и верхнюю границу цикла приходится всё время переопределять. Например, если наше перечисление определяло компоненты цвета, то мы может добави в него компонент определяющий яркость цвета:

Теперь в примере придётся изменить условие выполнение цикла на while(c . Если такой цикл один на всю программу, то в этом нет ничего страшного, но если подобный цикл встречается в десятке мест, то, рано или поздно, вы начнёте забывать все места где надо поменять предельное значение цикла, что приведёт к трудноуловимым ошибкам.

Другой пример, когда подобные проверки станут нашим кошмаром — валидация данных полученных из некоторого источника. Например сервер третьей стороны может передавать вам через сокет значения какого либо перечисления, и на каждое возможное значение вы выполняете различные действия. Представьте себе если администрация сервера добавила новый элемент в конец перечисления или же в сокет пришёл какой-либо мусор. Тогда вы заметите это лишь когда ваш клиент, слушающий сокет, отправит данные дальше и один из модулей, получив эти данные, рухнет. Решением в этом случае была бы проверка следующего вида:

И опять же если вы добавите новый элемент в перечисление, вам придётся внести изменения во все файлы где есть такие проверки. Есть решение проще — добавить фиктивный член перечисления, с фиксированным именем, всегда являющийся посленим членом перечисления. С нашим определением файла color.h сделать это — проще простого:

Output

Теперь вы можете добавлять сколько угодно членов в перечисление, не боясь ничего потерять (о неизменённых конструкциях switch вас предупредит компилятор).

Отображение run-time в compile-time

Я уже говорил что будут шаблоны?

Теперь представьте себе, что у вас есть семейство шаблонных функций вида template void f() , и, допустим, опять же через сокет к вам приходит число, и это для этого числа (интерпретированного как color ) нужно вызвать соответствущую функцию f . Простое решение напрашивается само собой:


Вопрос только в том сколько элементов может быть в перечислении и, опять же, сколько файлов вам придётся поправить, если в перечислении что-то изменится. Поэтому проще создать карту указателей на все эти функции, и отображать входное значение в указатель на функцию:

Значительно проще, не правда ли?

Обещанный пример

Усложним задачу. Теперь нам нужно не только отображать член перечисления в строку, но и наоборот. И при этом RED == -2 и BLUE == 5 . Используя стандартные перечисления добиться результата можно лишь напрямую забив данные в карту отображений.

Решение, на самом деле, очень простое, как и всё этой статье:

color.h

main.cpp

Output

Собственно получилось простенько, но со вкусом. Таким образом придерживаясь немного громоздкого стиля описания перечислений, вы можете достичь невероятной гибкости при их использовании.

Вот собственно и всё что я хотел здесь рассказать, если у кого-то возникнут вопросы — я с радостью на них отвечу. Буду рад если кому-то эта статья облегчит нелёгкую программистскую жизнь.

Если Вам понравилась статья, проголосуйте за нее

Перечисляемый тип

Перечисляемый тип

В си выделен отдельный тип перечисление (enum), задающий набор всех возможных целочисленных значений переменной этого типа. Синтаксис перечисления

В этой программе объявлено перечисление с именем Gender. Переменная типа enum Gender может принимать теперь только два значения – это MALE И FEMALE.

По умолчанию, первое поле структуры принимает численное значение 0, следующее 1, следующее 2 и т.д. Можно задать нулевое значение явно:

Будут выведены значения 0 1 0 1 2. То есть, значение SYMBOL равно значению EXPRESSION, а NUMBER равно OPERATOR. Если мы изменим программу и напишем

То SYMBOL будет равно значению 0, NUMBER равно 1, EXPRESSION равно 10, OPERATOR равно 11, UNDEFINED равно 12.

Принято писать имена полей перечисления, как и константы, заглавными буквами. Так как поля перечисления целого типа, то они могут быть использованы в операторе switch.

Заметьте, что мы не можем присвоить переменной типа Token просто численное значение. Переменная является сущностью типа Token и принимает только значения полей перечисления. Тем не менее, переменной числу можно присвоить значение поля перечисления.


Обычно перечисления используются в качестве набора именованных констант. Часто поступают следующим образом — создают массив строк, ассоциированных с полями перечисления. Например

Так как поля принимают численные значения, то они могут использоваться в качестве индекса массива строк. Команда exit(N) должна получать код ошибки, отличный от нуля, потому что 0 — это плановое завершение без ошибки. Именно поэтому первое поле перечисления равно единице.

Перечисления используются для большей типобезопасности и ограничения возможных значений переменной. Для того, чтобы не писать enum каждый раз, можно объявить новый тип. Делается это также, как и в случае структур.

Enum перечисление в языке программирования C#

Опубликовано shwan в 08.05.2020 08.05.2020

Перечисление (enum) — это набор именованных констант, позволяющих сделать исходный код программы более удобочитаемым. Оно позволяет задать имена для небольшого набора используемых целочисленных значений.

Зачем нужны перечисления (enum)?

Рассмотрим следующий пример. В рамках приложения нем необходимо иметь переменную, в которой будет храниться день недели. Для того, чтобы решить эту задачу можно просто завести целочисленную переменную, в которой хранить номер дня недели. Но тут возникает другая проблема, как вести отчет, от нуля или от единицы? А из этого вытекает следующая проблема, если ваш проект в дальнейшем будет поддерживать другой человек, у него могут возникнуть большие трудности, так как он не будет знать, что именно эти числа обозначают. Другой вариант, это хранить имя дня недели в строковой переменно, но и тут не все гладко, так как возникает вероятность опечатки, использования больших и маленьких букв и так далее.

Для решения подобных проблем отлично подходят перечисления — enum. Они позволяют создавать собственные миниатюрные типы данных и использовать из в исходном коде.

Объявление Enum

Наиболее полный обобщенный формат объявления перечисления выглядит следующим образом:

Давайте рассмотрим описанный выше пример с днями недели и объявим соответствующее перечисление:

Обратите внимание на несколько особенностей объявления перечисления. Рекомендуется давать имя перечисления во множественном числе и с большой буквы. Лучше всего использовать тип byte, если нужны значение больше либо равные нулю, или sbyte для отрицательных значений. Имена значений enum также пишутся с большой буквы, но в единственном числе. Рекомендуется задавать конкретные значения для каждого элемента enum для большей наглядности. Каждый элемент перечисления рекомендуется писать с новой строки. После последнего элемента можно оставлять запятую. Перечисления принято выносить в отдельные файлы или же создавать один файл, содержащий все перечисления проекта. Также для удобства можно рекомендуется добавлять xmldoc комментарии как ко всему перечислению, так и к каждому его элементу. И настоятельно не рекомендуется использование кириллицУ для имен элементов enum. Решение этой задачи подробно рассматривается в статье Отображение значения Enum в C# на русском.

Но enum можно объявлять и в более сжатом формате. По умолчанию используется тип int, нумерация ведется с нуля.

Использование перечислений (enum)

Для того, чтобы обратиться к перечислению, необходимо просто указать имя перечисления и его значение через точку. Enum могут использоваться в качестве аргументов метода, что делает код намного более читаемым, чем использование «магических переменных».

Обратите внимание, что имеется возможность взаимного приведения чисел и перечислений. То есть мы можем приводить как целое число из возможного диапазона к перечислению,

так и в элемент перечисления к целому числу

Заключение

Использование Enum в коде считается очень хорошей практикой среди программистов. Это позволяет сделать код намного более читаемым и легко масштабируемым.

Также рекомендую прочитать статью Принципы SOLID C#. И не забудьте подписывайтесь на группу ВКонтакте, Telegram и YouTube-канал. Там еще больше полезного и интересного для программистов.


C++ — Урок 008. Перечисления

В дополнение к классам C++ поддерживает перечисления. В современном стандарте C++ поддерживаются как перечисления без области видимости, которые были введены в ранних версиях C++, а также C.

Так и перечисления с областью видимости

Отличие перечислений с областью видимости от перечислений без области видимости

Отличие перечисление с областью видимостью отличается от перечислении без области видимости тем, что переменные перечислений с областью видимости не могут неявно преобразовываться в целочисленные переменные и обратно. Для такого преобразования следует использовать static_cast ().

Подобный контроль областей видимости позволяет объявлять в классе перечисления, члены которых имеют одинаковые имена. Также предоставляет больший контроль над кодом, хотя и накладывает ряд ограничений.

Как задаются значения перечислений

По умолчанию перечиление начинается с 0, и дальше происходит инкремент членов перечисления.

но имеется возможность задавать собственные значения для перечислений при объявлении.

Использование switch case для перечислений

Перечисления как с областью видимости, так и без области видимости поддерживают операторы условий и ветвления switch/case :

Если рассуждать о контроле выполнения кода и накладывающихся ограничениях при использовании перечислений с областью видимости и без области видимости, то можно смоделировать ситуацию, когда в switch/case по какой-то причине (опечатка, копипаста, нуб, напортачили при разрешении конфликтов при мердже веток) попадают перечисления разных типов. Тогда перечисления без области видимости будут неявно преобразованы в нужный тип компилятором и код выполнится, хотя и будет ошибочен, а в случае с перчислениями с областью видимости компилятор сообщит об ошибке и прекратит сборку программы.

То есть, ниже следующий код, будучи ошибочным, скомпилируется:

В лучшем случае компилятор выкинет Warning.

Но бывает же так, что программист «лучше компилятора знает и понимает С++», и отключает предупреждения.

Тогда как следующий код просто не скомпилируется:

Копилятор выдаст ошибку компиляции:

Как задать конкретный целочисленный тип для перечисления

Перечисления также могут иметь более конкретизированный тип, который должен быть определённым целочисленным типом:

Это позволяет выделить определённый объём памяти под переменные, которые имеют значения перечислений. Пожалуй, это может быть актуально для embedded разработки. В зависимости от целевой платформы будет выделяться определённый объём памяти.

Итератор для перечисления


И напоследок сделаем итератор для перечислений, с помощью которых можно использовать range-based цикл for .

Рекомендуем хостинг TIMEWEB

Рекомендуемые статьи по этой тематике

Класс Enum С++ 11 по ссылке или значению

У меня в основном два вопроса, возможно, они связаны, поэтому я помещу их в один.

Должен ли мы передавать класс enum в С++ 11 по ссылке или значению при передаче функции. Это своего рода наследующий примитивный тип, но является ли он всем объектом, который передается? поскольку классы enum безопасны по типу;

Теперь скажем, что у нас есть функция sig

мой другой вопрос здесь —

Он не наследует примитивный тип, а скорее указывает разработчику использовать указанный тип ( unsigned short ) в качестве базового типа для счетчиков.

Вы можете просто рассматривать объект класса enum как любой другой объект класса и применять те же правила, передавая его функциям.

  • Если вы хотите изменить объект класса enum внутри функции, передайте его по ссылке.
  • Если вы просто хотите прочитать объект внутри функции, передайте его по постоянной ссылке.

Перенос семантики — это функция повышения производительности во время выполнения, которая использует возможности перехода от rvalues ​​вместо применения семантики копирования, которые имеют высокую производительность. Ссылки r-value и семантика перемещения не ограничиваются только перемещением конструктора и оператора присваивания, но они также могут использоваться с другими функциями. Если у вас есть сценарии, которые могут использовать эту оптимизацию, отлично использовать их.

Учитывая, что перечисляющие используют указанный тип unsigned short как базовый тип, как указывал Alok Save, вероятно, хорошая идея передать такие объекты по значению (если вы не хотите изменить их значение в функции как побочный эффект, и в этом случае вы должны использовать ссылку.)

Перечисления в С++ (enum)

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

С помощью ключевого слова enum можно описать свой собственный тип данных, переменные которого принимают строго определенные целочисленные значения. Почти всегда можно обойтись без него, но перечисления улучшают качество кода.

Перечисления позволяют создавать новые типы данных. Переменная этого нового типа может принимать какое-то ограниченное количество значений. Объявляются перечисления так:

При этом название перечисления ( EnumType ) является типом данных, с помощью которого мы сможем объявить переменную типа перечисления:

Например, новый тип данных, который обозначает день недели, мы объявим вот так:

При этом значение Mondey приравнивается к 1, Tuesday — к значению 2 и т.д. Но если мы при объявлении этого перечисления напишем, скажем, кот так: Wednesday = 17, то значение Wednesday будет 17, значение Thursday — это 18 и т.д. Попробуйте составить какую-нибудь программу с этим перечислением или придумайте свои типы данных, поинтересней.


Примеры использования enum

Используется эта конструкция очень часто, например тут: Спрайтовая анимация на QGraphicsScene Qt описана игрушка, в которой персонаж может двигаться в разные стороны. Дак вот, переменная, которая хранит направление движения имеет тип перечисления:

Правда тут используется не просто enum , а enum class — прочитать про особенности которого можно тут: Зачем нужен enum class .

Также, обратите внимание как часто используются enum-ы в стандартной библиотеке… Вы хотите открыть файл — тогда вы пишите что-то такое:
fs.open («test.txt», fstream::in | fstream::out | fstream::app);

Вот эти fstream::out — не что иное как перечисления. А как их умудрились описать так, чтобы использовать совместно с оператором логического ИЛИ — можно узнать тут: enum и наложение масок.

В начале я говорил, что без enum почти всегда можно обойтись. Ну, в самом деле, кто мне мешает вместо Monday везде писать 2 и радоваться? — дело в том, что такая техника дает нечитаемый код. Откуда другому человеку знать с какого дня у вас начинается неделя? — целые страны первым днем считают воскресенье, а кто-нибудь обязательно начнет нумерацию с единицы, а не так как вы… Решение очевидно — именовать константы. Именовать — хорошо, но enum позволяет еще и сгруппировать, а это еще лучше. Впрочем, это тесня связано с понятием Чистоты кода.

вернуть enum или передать enum по ссылке?

У меня есть процедура, которая выполняет некоторую задачу, но выполняет ее двумя слегка различными способами в зависимости от ее ввода. В частности, он расширяет суффикс в дереве суффиксов; если суффикс заканчивается в узле, то дело простое, но когда суффикс заканчивается в пределах края листа, требуется дополнительная работа. Я упоминаю эту деталь, чтобы объяснить, почему я включил эти два поведения в одну функцию (она отражает «Правило 2» описания Дэном Гусфилдом алгоритма Укконена для построения дерева суффиксов: http://www.stanford.edu/

В любом случае, когда функция завершает эту работу, вызывающая сторона должна знать, какой из двух случаев был соблюден. Я думал, что перечисление было бы хорошим способом поделиться этой информацией, поскольку это делает случаи явными (в отличие от произвольного отображения случаев в bools или ints).

TLDR: Чтобы поделиться информацией с вызывающим абонентом, должен ли я передать перечисление по ссылке на эту процедуру или вернуть перечисление? Я чувствую, что передавать перечисление по ссылке лучше, потому что он избегает «функции с побочными эффектами», но хотел бы знать, существует ли вообще «правильный» способ сделать это. Или, наоборот, действительно ли это говорит о том, что я должен заменить свою единственную процедуру двумя отдельными процедурами?

4 ответа

По моему мнению, имеет смысл возвращать enum, так как это результат вызова функции. Использование ссылки имело бы гораздо больше смысла, если бы вы передавали значение функции, и функция должна была изменить это значение.

Вы можете увидеть похожий пример в методе insert из unordered_map в стандартной библиотеке C ++:

Этот метод возвращает логическое значение (в паре), указывающее, было ли значение вставлено в карту или нет. На самом деле это очень похоже на тот случай, с которым вы имеете дело.

Я думаю, что лучше возвращать enum как результат функции, так как его легче читать и писать проще:

Я чувствую, что передавать перечисление по ссылке лучше, потому что в нем нет «функции с побочными эффектами».

Наоборот, вообще-то . вообще, если вы измените свои аргументы, это побочный эффект.

Там нет причин, чтобы избежать возврата чего-либо.

Перечисления являются просто целочисленными значениями, когда они хранятся в памяти, и компиляторы осуществляют проверку диапазона значений, используемых для перечисления. Сказав, что целочисленные типы данных являются эффективными и безопасными для возврата по значению.

Если функция действительно не возвращает более одного значения, вызывающей стороне не нужно передавать перечисление в качестве ссылки и возвращать результат.

PS: Правило, которое я обычно придерживаюсь, чтобы решить, следует ли возвращать значение или заставить вызывающего передать указатель / ссылку и вернуть значение, если возвращаемые данные имеют простой или сложный тип данных. ;)

Цукерберг рекомендует:  34 примера адаптивных портфолио
Понравилась статья? Поделиться с друзьями:
Все языки программирования для начинающих