Войти

Показать полную графическую версию : [решено] Непонятка при присвоении значения переменной, имеющей тип: перечисление.


Oleg_SK
01-12-2008, 11:08
Начал изучать язык 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)? Почему компилятор не пресекает подобные действия?

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

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

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

pva
03-12-2008, 15:16
Мне хотелось бы сохранить возможность преобразования int в enum. »
зачем? так хочешь чтобы преобразовывалось(противоречит первому посту) или нет?
Проблема в том, что компилятор не дает мне при создании нескольких разных типов-перечислений использовать в качестве одного из их возможных значений одноименную константу »
это чтобы не перепутать:

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
03-12-2008, 19:27
pva
это чтобы не перепутать: »
А что это ещё? помойму они и есть »
Понятно... Придется приспосабливаться, но все равно остается чувство, что это не правильно (во всяком случае, я бы это сделал не так). Ну да ладно - не впервой...

pva
04-12-2008, 07:22
Меня в 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
не забываем помечать решённую тему ;-)




© OSzone.net 2001-2012