枚举类的超出范围值

时间:2017-07-22 06:20:36

标签: c++ c++11 enum-class

当我在函数中定义enum class时,它具有可用选项中的值。但是,当我在一个类中定义它时,它没有任何选项的值。那么g.f的初始值是多少?比较时会返回true的内容? ((g.f==??)==true)

#include <iostream>

enum class Fruit
{
    apple,
    orange
};

class Garden
{
public:
    Fruit f;
};

void print_enum(Fruit f)
{
    switch(f)
    {
        case Fruit::apple:
            std::cout<<"apple\n";
            break;
        case Fruit::orange:
            std::cout<<"orange\n";
            break;
        default:
            std::cout<<"other\n";
            break;
    }   
}

int main()
{
    Garden g;
    Fruit f;

    print_enum(f); // apple
    print_enum(g.f); // other

    return 0;
}

2 个答案:

答案 0 :(得分:1)

始终初始化您的变量,C ++并没有使用&#34;默认&#34;来初始化它们。价值在几个场合。

在这两种情况下,你都写在这里,你受到编译器和操作系统的支配,但你可能会在garbage变量中得到enum(这可能是{}}你在后一种情况下的实验)如果您想查看garbage是什么,请执行以下命令:

std::cout << (int)g.f << std::endl;

答案 1 :(得分:1)

该标准规定,访问自动存储持续时间的未初始化变量的值会产生不确定的行为。

结果是任何依赖于访问该值的操作都会产生未定义的行为。访问变量的值是必要的;

  • 将其与其他值进行比较。例如,如果a == ba未初始化,则b会给出未定义的行为。如果a == a未初始化,即使比较a也会给出未定义的行为。
  • 将值分配给另一个变量。例如,如果a = b未初始化,b会给出未定义的行为。
  • 按值传递给函数。对于函数f(),如果f(a)未初始化,则调用a将提供未定义的行为。
  • 输出值。例如,如果std::cout << a未初始化,a会给出未定义的行为。

因此,要求未初始化的变量具有特定值是没有意义的。访问该值会给出未定义的行为,因此测试它是否等于(或不等于,或大于,或......)任何值都会产生未定义的行为。

这通常通过将未初始化的变量的值描述为 indeterminate 来概括。如果在不引入未定义行为的情况下无法访问值,则无法可靠地确定该值是什么。

当然,有一个问题是标准为什么认为访问未初始化变量的值会给出未定义的行为。保留值未初始化允许编译器为变量分配内存(例如,从堆栈中)但不打扰初始化 - 该内存中的数据可以是任何恰好存在的数据。将变量初始化为任何指定值可能是昂贵的操作(例如,两百万个元素的数组是变量,虽然是大变量,并且初始化它可能在计算上是昂贵的)。它通常也是一种不必要的操作,因为很多代码对初始化变量做的第一件事是(等待它......)为它赋值,即初始化它。

(可能)不必要且计算上浪费的操作往往不受程序员和编译器供应商的欢迎。使行为未定义会消除所有这些......尽管要求程序员在访问其值的任何操作之前要小心初始化它们的变量。