【问题标题】:Default value of an unset boolean in C++? [duplicate]C ++中未设置的布尔值的默认值? [复制]
【发布时间】:2011-12-13 10:03:03
【问题描述】:

可能重复:
Why is a C++ bool var true by default?

假设我要做这样的事情:

class blah
{
  public:
  bool exampleVar;
};

blah exampleArray[4];
exampleArray[1].exampleVar = true;

在 exampleArray 中,现在有 3 个未设置的 exampleVar 实例,如果我没有设置它们,它们的默认值是多少?

【问题讨论】:

  • 难怪之前的版本没有出现在搜索中,而且这个标题更好,但答案是一样的。如果自动或分配有newmalloc bools 有no 默认值。你只会得到内存中的内容。静态或全局变量初始化为0 == false

标签: c++ boolean


【解决方案1】:
struct x
{
    bool b;

    x() : b() { }
}

...
x myx;

在这种情况下,myx.b 将为 false。

struct x
{
    bool b;
}

...
x myx;

在这种情况下,myx.b 将是不可预测的,它将是分配 myx 之前内存位置的值。

由于在 C 和 C++ 中,假值定义为 0,真值定义为非零,因此随机地址位置包含真值而不是假值的可能性更大。通常,在 C++ 中,sizeof(bool) 为 1,即 8 位。内存的随机位置有 1 到 255 种可能性为假,这解释了为什么您将默认布尔值视为真。

【讨论】:

    【解决方案2】:

    默认值取决于声明 exampleArray 的范围。如果它是函数的本地值,则无论这些堆栈位置碰巧处于什么值,这些值都是随机的。如果它是静态的或在文件范围内声明(全局),则值将初始化为零。

    Here's 演示。如果您需要成员变量具有确定性值,请始终在构造函数中对其进行初始化。

    class blah
    {
      public:
      blah() 
      : exampleVar(false)
      {}
    
      bool exampleVar;
    };
    

    编辑:
    C++11 不再需要上述示例中的构造函数。数据成员可以在类声明本身中初始化。

    class blah
    {
      public:
      bool exampleVar = false;
    };
    

    如果需要,这个内联默认值可以被用户定义的构造函数覆盖。

    【讨论】:

    • +1 用于捕捉细微差别。
    • 您可能还需要注意,您可以使用零初始化来确保在该类不是您的类时初始化值,因此您不能添加构造函数。
    • +1:非常有趣。你回答了我的问题等等。 :D
    • 严格来说,它取决于对象的storage duration(生命周期),而不是它的范围。例如,如果您在函数内定义static bool b;b 具有静态存储持续时间(因此是零初始化)但块范围。 (在文件范围内定义的对象只能具有静态存储持续时间。)此外,初始值不是严格随机,它是任意的——这意味着如果它碰巧是你不应该感到惊讶false 100 次中有 99 次。
    • 函数的局部,取决于编译器优化的级别,默认值可以是变量分配到的特定寄存器中发生的任何值,不一定是堆栈上的数据位置。
    【解决方案3】:

    @Praetorian:在他的回答中涵盖了要点。

    但也值得注意。

    blah exampleArray[4];         // static storage duration will be zero-initialized 
                                  // ie POD member exampleVar will be false.
    
    void foo()
    {
        blah exampleArray1[4];    // automatic storage duration will be untouched.
                                  // Though this is a class type it only has a compiler 
                                  // generated constructor. When it is called this way 
                                  // it performs default-construction and POD members
                                  // have indeterminate values
    
    
        blah exampleArray2[4] = {};  // Can force zero-in initialization;
                                     // This is list-initialization.
                                     // This forces value-initialization of each member.
                                     // If this is a class with a compiler generated constrcutor
                                     // Then each member is zero-initialized
    
    
        // following through to non array types.
        blah       tmp1;            // Default initialized: Member is indeterminate
        blah       tmp2 = blah();   // Zero Initialized: Members is false
    
        // Unfortunately does not work as expected
        blah       tmp3();          // Most beginners think this is zero initialization.
                                    // Unfortunately it is a forward function declaration.
                                    // You must use tmp2 version to get the zero-initialization 
    }
    

    【讨论】:

      【解决方案4】:

      默认值为不确定。每次运行程序时可能会有所不同。您应该将值初始化为某个值或使用另一个变量来指示您的私有成员未初始化。

      【讨论】:

      • 最好叫undefined而不是random。
      • @ObscureRobot - 或者更准确地说是 indeterminate
      • @above 感谢您更正措辞 :)
      【解决方案5】:

      不确定。

      非静态成员变量需要初始化,除非你能保证对它们执行的第一个操作是写操作。最常见的方法是通过构造函数。如果您仍然需要无参数/无操作构造函数,请使用初始化列表:

      public:
      blah() : exampleVar(false) {}
      

      【讨论】:

        【解决方案6】:

        未分配的默认值在 C/C++ 中未定义。如果你需要一个特定的值,那么为类 blah 创建一个构造函数并设置你的默认值。

        【讨论】:

          【解决方案7】:

          它们的默认值是未定义的。您不应该依赖它们被设置为一件事或另一件事,并且通常被称为“垃圾”。

          根据您的编译器,它可能设置为false。但即便如此,最好还是设置它们。

          【讨论】:

          • 我不确定它的未定义。编译器应该调用类中每个字段的构造函数,bool 的构造函数可能会将其设置为 false。
          • 更糟糕的是,您的编译器可能在您进行调试构建而不是发布构建时初始化内存。
          • @Dani 在上面给出的例子中,没有构造函数,也没有设置exampleVar。
          • @ObscureRobot:当没有构造函数时,c++ 提供了它的默认构造函数,它调用成员的所有构造函数
          • @Dani 只调用用户定义类型的默认构造函数,而不是原始类型
          猜你喜欢
          • 2020-05-21
          • 2016-04-20
          • 2019-04-21
          • 2018-10-14
          • 1970-01-01
          • 2014-02-25
          • 2013-03-06
          • 2019-11-09
          • 2015-03-28
          相关资源
          最近更新 更多