3

我有一门简单的课,比如

class Person {
  static const int MALE; // in Person.cpp initialized = 1
  static const int FEMALE;//in Person.cpp initialized = 2
};

在公司类(Company.cpp 文件,我有公司类)中,我具有开关功能

 switch(x){// x is int passed as parameter to function
        case Person::MALE:
            //do something
        break;
        case Person::FEMALE:
            //do something
        break;
}

但是当我尝试构建时 error C2051: case expression not constant,如果在上面的 switch 中出现错误,当它是 const 时有什么问题?

4

5 回答 5

10

通过以下方式更改静态数据成员的声明

class Person {
  static const int MALE = 1;
  static const int FEMALE = 2;
};

编译器必须在编译期间知道 case 标签的值。

于 2013-10-18T14:58:23.647 回答
3

Aconst不是常量表达式,除非

  • 它是一个const整数类型的变量,之前用文字或其他常量表达式初始化。

C++11 增加了constexpr,它可以与非整数类型的变量一起使用,但对事先初始化的要求仍然适用。

您的问题是在 Company.cpp 中,此变量尚未初始化。编译器必须假设实际定义涉及运行时计算。例如,写是完全合法的const int Person::MALE = rand();

或者如果 Person.cpp 包含

const int Person::MALE = 1;
const int Person::FEMALE = 1;

那么编译器将不得不拒绝 Company.cpp,因为案例不是唯一的。那将如何运作?如果有人在 Company.cpp 已经编译后编辑 Person.cpp 怎么办?

于 2013-10-18T15:00:24.380 回答
1

表达式中使用的值case在编译时应该是已知的,因为它们在某种程度上被“硬编码”成二进制代码。在这里,它们仅在链接阶段指定。可能解决方案可能如下:

// person.h
enum Person { MALE, FEMALE };
于 2013-10-18T15:00:02.597 回答
1

根据 C++11 标准:如果表达式包含左值到右值的转换,则表达式不是常量表达式, 除非它应用于“引用非易失性 const 对象的整数或枚举类型的左值前面的初始化,用常量表达式初始化”。(还有其他一些情况,但它们不适用于此处。)注意“预先初始化”的要求;不仅变量必须是 const,而且编译器必须能够看到它的初始化。

该标准的早期版本在这方面有些模糊,对他们字面意思的自然解释表明您的代码是合法的。然而,这当然不是本意。没有编译器以这种方式实现它(因为它通常需要打破单独的编译),而 C++11 明确表示这是非法的。

于 2013-10-18T15:03:44.243 回答
0

C++ 不是 Java。使用枚举:

enum Person
{
  Person_male = 1,
  Person_female = 2
};
于 2013-10-18T15:02:08.083 回答