Подтвердить что ты не робот

Значение по умолчанию для bool в С++

Я перепроектирую конструктор класса в С++ и нуждаюсь в нем, чтобы поймать неуказанный bool. Я использовал значения по умолчанию для всех других параметров, но из моего понимания bool может быть инициализирован только true или false. Поскольку оба этих случая имеют смысл в классе, как мне обрабатывать проверку на изменение по умолчанию?

4b9b3361

Ответ 1

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

Если вам нужен тип с большим количеством опций, укажите перечисление.

typedef enum MyBool {
    TRUE,
    FALSE,
    FILENOTFOUND
} MyBool;

Ответ 2

Tristate bool - это путь к темной стороне. Tristate bool приводит к гневу. Гнев ведет к ненависти. Ненависть ведет к страданиям.


Предпочитают не использовать tristate bool.

Вместо этого используйте одно дополнительное логическое значение для того, является ли первое логическое значение "инициализировано" (или лучше, "известно" ) или нет.

class Prisoner : public Person
{


  ...

  bool is_veredict_known;
  bool is_guilty;
}

Если вердикт пока не известен, вы не можете сказать, действительно ли Заключенный виноват, но ваш код может различать разные ситуации. Конечно, Конституция гарантирует, что значение по умолчанию is_guilty должно быть ложным, но все же...:)

Кстати, инвариант класса должен включать:

assert(is_veredict_known || !is_guilty);

Ответ 4

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

template <typename T>
struct Maybe {
  Maybe() : m_hasValue(false) {}
  bool HasValue() const { return m_hasValue; }
  T& Value() { ThrowIfFalse(m_hasValue); return m_value; }
  const T& Value() const { ThrowIfFalse(m_hasValue); return m_value; }
  void SetValue( _In_ const T& value) { m_value = value; m_hasValue = true; }
private:
  bool m_hasValue;
  T m_value;
};

Теперь вы можете представить все 3 состояния, которые вам нужны.

class SomeType { 
  ...
  Maybe<bool> m_myBool;
}

Ответ 5

В С++ a bool - это только один бит информации, либо 0, либо 1. Поскольку вы хотите представить три возможных состояния, вам нужен еще один бит информации. Существует два общих метода:

  • Используйте другое значение bool, чтобы указать, является ли значение "по умолчанию" или нет, или
  • Используйте тип перечисления с тремя значениями для указания (по умолчанию, true, false).

Я бы выбрал вариант 1.

Ответ 6

Используйте большой boost:: optional. И не только для bools, но и для всех других мест, которые вы использовали некоторые грязные not-initialized-values ​​in. Он используется следующим образом:

void function(optional<int> value) {
   if (value)
      std::cout << "value is defined: " << value.get() << "\n";
   else
      std::cout << "value is not defined\n";
}

И вот пример функции, возвращающий необязательный параметр:

struct MapClass {
   map<string,int> m_map;

   optional<int> getValue(string key) {
      optional<int> result = none;
      if (m_map.find(key) != m_map.end())
         result = m_map[key];
      return result;
   }
}

Ответ 7

struct Bool { //guaranteed initialized bool
    bool v;

    Bool() : v(false) {}
    operator bool() const { return v; }
    bool& operator=(const bool val){ return v = val; }
};

Ответ 8

У вас может быть отдельный частный член, который указывает, действительно ли значение bool было инициализировано или нет.

Ответ 9

Я не совсем понимаю, но я попробую...

Значения по умолчанию применяются, если у вас есть агрегатный инициализатор, который оставляет некоторые значения неопределенными. В этом случае bool default будет false. В классе значение "default" будет неинициализировано, то есть оно может быть любым значением и может меняться от run to run.

Если вас интересует, изменился ли bool или нет, ваш лучший вариант - отслеживать его со вторым значением bool по умолчанию, равным false, или использовать перечисление, представляющее 3 возможных состояния. Если вы действительно хотите 3 состояния, вы действительно не хотите bool.

Ответ 10

Ты действительно не можешь. Не могли бы вы предоставить второй конструктор, например:

class MyClass {
  public:
    MyClass(bool bFlag); // <-- not default
    MyClass(void);       // <-- default
};

Ответ 11

Вместо логического, используйте перечисление. Например, чтобы контролировать уровень магии:

enum {
    MY_ENUM_NO_MAGIC,
    MY_ENUM_SOME_MAGIC,
    MY_ENUM_MORE_MAGIC
} MagicLevel;

Затем ваш конструктор принимает параметр MagicLevel magic = MY_ENUM_NO_MAGIC.

Ответ 12

class aclass
{
    <stuff> lots of other things
    bool mybool
    bool ismyboolinit

    void setmybool(bool b)
    {
        mybool = b;
        ismyboolinit = true;
    }

}

Ответ 13

Хорошо, если вы используете функции и классы, просто перегрузите их.

т

    class thing
{
  public:
   void f1(bool); // bool input
   void f1(int = 3); // default with out bool being known
  private:
   // stuff
};     
void thing::f1 (bool hasAFace)
{
  if(hasAFace)
   f1(0);
  if(!hasAFace)
   f1(1);

}

void thing::f1 (int tri)
{
  bool actionTime;
  if(tri == 1)
    actionTime = true;
   else if(tri == 0)
    actionTime = false;
   else
    //input defualt action here.
} 

//и там вы идете. Также вам не нужно иметь класс, в котором вы могли бы просто использовать перегруженные функции.