Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - [решено] Непонятка при присвоении значения переменной, имеющей тип: перечисление.

Ответить
Настройки темы
C/C++ - [решено] Непонятка при присвоении значения переменной, имеющей тип: перечисление.

Аватара для Oleg_SK

Ветеран


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


Конфигурация

Профиль | Отправить PM | Цитировать


Начал изучать язык C++, и дойдя до перечислений столкнулся с непонятной для себя ситуацией при присвоении значения переменной, имеющей тип: перечисление. Как я понимаю, перечисления нужны для создания новых типов переменных, для которых четко задано то множество значений, которое им можно присваивать. Ниже я приведу факты, которые не укладываются в мое представление. Например, возьмем следующий код:
Код: Выделить весь код
enum COLOR {test_1, test_2, test_3, test_4, test_5};
, который создает новый тип-перечисление COLOR и задает для него пять возможных значений. Теперь по идее, если создать переменную с типом COLOR, ей можно будет присвоить только одно из этих пяти значений, а попытка присвоить какое-либо отличное значение должно привести к ошибке. Верно я понимаю? Идем дальше: каждой константе перечисления соответствует определенное целочисленное значение. Например:
test_1 - 0
test_2 - 1
test_3 - 2
test_4 - 3
test_5 - 4
Таким образом, по идее, если я создам переменную с типом COLOR:
Код: Выделить весь код
COLOR vartest;
, то в последствии смогу присвоить ей лишь те значения, которые указывались при описании перечисления. Например так:
Код: Выделить весь код
vartest = test_5;
, или так:
Код: Выделить весь код
vartest = (COLOR) 4;
Никаких проблем при этом, как и следовало ожидать, не возникает. Непонятка возникает в том случае, если присвоить переменной vartest значение, которое не было указано при описании перечисления COLOR. Дело в том, что компилятор не считает такой код ошибочным (при компиляции нет ни ошибок, ни предупреждений), и действительно в процессе работы программы переменной vartest присваивается левое значение... Например:
Код: Выделить весь код
vartest = (COLOR) 1000;
Мне хотелось бы знать: это я не правильно понимаю суть работы с перечислениями, или компилятор (Visual C++ 6.0)? Почему компилятор не пресекает подобные действия?

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

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

Отправлено: 11:08, 01-12-2008

 
pva pva вне форума

Аватара для pva

Ветеран


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

Профиль | Отправить PM | Цитировать


Цитата Oleg_SK:
vartest = (COLOR) 4; »
это грубый хак. Когда используются сишные, а не плюсплюсные преобразования типов, используются сишные правила. А они это позволяют. Чтобы такого не было, нужно в настройках компилятора поставить галочку, запрещающую преобразование int в enum
Это сообщение посчитали полезным следующие участники:

Отправлено: 11:58, 01-12-2008 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

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


Аватара для Oleg_SK

Ветеран


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

Профиль | Отправить PM | Цитировать


pva
Цитата pva:
Когда используются сишные, а не плюсплюсные преобразования типов, используются сишные правила. А они это позволяют. »
Понятно... Подскажите, плиз, как сделать сиплюсплюсное приведение типа, чтобы указанная выше ситуация пресекалась? В том месте книги, где я читаю указано только два варианта для этого действия:
1) Я им пользовался в своем примере в первом посте;
2) С помощью static_cast. Например:
Код: Выделить весь код
vartest = static_cast <COLOR> (1000);
В обоих случаях имеет место обсуждаемая непонятка.
Цитата pva:
Чтобы такого не было, нужно в настройках компилятора поставить галочку, запрещающую преобразование int в enum »
Мне хотелось бы сохранить возможность преобразования int в enum.

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

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


Отправлено: 13:21, 03-12-2008 | #3

pva pva вне форума

Аватара для pva

Ветеран


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

Профиль | Отправить PM | Цитировать


Цитата Oleg_SK:
Мне хотелось бы сохранить возможность преобразования int в enum. »
зачем? так хочешь чтобы преобразовывалось(противоречит первому посту) или нет?
Цитата Oleg_SK:
Проблема в том, что компилятор не дает мне при создании нескольких разных типов-перечислений использовать в качестве одного из их возможных значений одноименную константу »
это чтобы не перепутать:
Код: Выделить весь код
enum ColumnAlign
{
   left, right, center
};

enum RectField
{
   left, right, bottom, top
};

void Column::setAlign(ColumnAlign);
void MyRect::getField(RectField);
void MyLink::attach(ColumnAlign, RectField);
Цитата Oleg_SK:
Зачем сделали возможные значения перечислений доступными коду как обычные константы? »
А что это ещё? помойму они и есть
Это сообщение посчитали полезным следующие участники:

Отправлено: 15:16, 03-12-2008 | #4


Аватара для Oleg_SK

Ветеран


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

Профиль | Отправить PM | Цитировать


pva
Цитата pva:
это чтобы не перепутать: »
Цитата pva:
А что это ещё? помойму они и есть »
Понятно... Придется приспосабливаться, но все равно остается чувство, что это не правильно (во всяком случае, я бы это сделал не так). Ну да ладно - не впервой...

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


Отправлено: 19:27, 03-12-2008 | #5

pva pva вне форума

Аватара для pva

Ветеран


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

Профиль | Отправить PM | Цитировать


Меня в enum смущает только одно:
Код: Выделить весь код
class ListView
{
public:
    enum column_align_t {ca_left, ca_right, ca_center};
    ...
};

// правильно так:
listView1.setColumnAlign(1, ListView::ca_left);
// но логичней так:
// listView1.setColumnAlign(1, ListView::column_align_t::ca_left);
тем не менее, как видно из примера, указание имени перечисления усложняет чтение и почти не вносит большей понятности в код. Хотя когда этих enum с десяток, нужно грамотно называть их элементы, чтоб не запутаться. Я как правило называю элементы enum XXX_t именами XXX_value
не забываем помечать решённую тему ;-)
Это сообщение посчитали полезным следующие участники:

Отправлено: 07:22, 04-12-2008 | #6



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - [решено] Непонятка при присвоении значения переменной, имеющей тип: перечисление.

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
CMD/BAT - [решено] Реализация функций длины переменной, выделение подстроки с параметрами в переменной. NiOl Скриптовые языки администрирования Windows 7 31-01-2019 19:58
MySQL - Хранение значения переменной в MySQL-базе ManHack Программирование и базы данных 7 11-07-2009 10:02
VBS/WSH/JS - [решено] Stop цикл при обнаружении нужного значения из файла Afon Скриптовые языки администрирования Windows 4 26-01-2009 15:16
VBS/WHS/JS - Вывод значения переменной в сообщение la_vanille_ciel Программирование и базы данных 3 09-04-2008 11:55
php деление значения строковой переменной Guest Вебмастеру 4 14-10-2004 17:12




 
Переход