Использование значений по умолчанию в C ++

Это обсуждение о названии значения по умолчанию:
C #: Должно ли значение по умолчанию для перечисления быть None или Unknown?

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

В качестве примера рассмотрим следующее:

enum eJobStates
{
JOB_STATE_INITIALISING,
JOB_STATE_PROCESSING,
JOB_STATE_DONE
};

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

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

6

Решение

Недопустимое значение по умолчанию — в основном вариант в вашем дизайне. Объект недействителен при его создании. Вы должны избегать этого, когда это разумный. Ни в коем случае не следует избегать этого «любой ценой».

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

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

namespace FooType {
enum EnumValue {
INVALID = 0
,valid
};
}

struct Foo {
Foo() : val(FooType::INVALID) {}
FooType::EnumValue get() const {
if (val == FooType::INVALID)
throw std::logic_error("variant Foo state");
return val;
}
FooType::EnumValue val;
};

Это освобождает ваших пользователей от необходимости рассуждать о вашем отклонении, за которое стоит бороться.

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

struct Foo {
Foo() : val(FooType::INVALID) {}
bool get(FooType::EnumValue& val_) const {
if (val == FooType::INVALID)
return false;
val_ = val;
return true;
}
FooType::EnumValue get() const {
FooType::EnumValue val_;
if (!get(val_))
throw std::logic_error("variant Foo state");
return val_;
}
FooType::EnumValue get_or_default(FooType::EnumValue def) const {
FooType::EnumValue val_;
if (!get(val_))
return def;
return val_;
}
FooType::EnumValue val;
};

Эти виды интерфейсов хороши для таких вещей, как базы данных, где можно ожидать нулевые значения.

2

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector