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

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

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

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

enum eJobStates
{
    JOB_STATE_INITIALISING,
    JOB_STATE_PROCESSING,
    JOB_STATE_DONE
};

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

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


person ellimilial    schedule 17.12.2012    source источник
comment
Хорошо, можете ли вы сделать так, чтобы ваш класс мониторинга «расширил» перечисление, добавив значение MONITORING_STATE?   -  person dchhetri    schedule 18.12.2012
comment
Возможно, я не совсем понимаю предложение. В этом конкретном примере MONITORING_STATE по-прежнему не имеет большого смысла с точки зрения работы и, согласно ссылке Я не могу расширить перечисление в классе мониторинга (который в идеале использует eJobStates в качестве частной переменной).   -  person ellimilial    schedule 18.12.2012
comment
Да, я понимаю, что вы не можете естественным образом расширять перечисления. Monitoring_state - это просто имя, но вы определенно можете использовать job_state_unknown. Мне было предложено добавить дополнительное перечисление в класс мониторинга. Вы можете сделать это, взяв последнее значение перечисления eJobStates и добавив к нему 1, и сделав его начальным значением состояния перечисления для класса мониторинга. В конце концов, с перечислениями вы просто сравниваете целые числа, представляющие состояния. Если вам нужно что-то более конкретное, то, как предлагается в ссылке, вы можете либо создать класс Enum, либо создать объект состояния для каждого состояния.   -  person dchhetri    schedule 18.12.2012


Ответы (1)


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

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

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

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;
};

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

person Tom Kerr    schedule 19.12.2012