C与C ++中枚举的范围

时间:2015-05-05 07:46:51

标签: c++ c enums

为什么枚举值可以在用C语言定义枚举的块之外访问,而不是用C ++定义?

考虑以下C程序。

#include <stdio.h>
struct mystruct
{
    enum {INT, FLOAT, STRING} type;
    int integer;
    float floating_point;
} tu;

/* Why is INT accessible here? */
int main()
{
    tu.type = INT;
    tu.integer = 100;
    return 0;
}

它在C中编译并运行良好。

但是在C ++中,编译失败了。

#include <iostream>
struct mystruct
{
    enum {INT, FLOAT, STRING} type;
    int integer;
    float floating_point;
} tu;

/* Why is INT accessible here? */
int main()
{
    tu.type = INT;
    tu.integer = 100;
    return 0;
}
  

[错误]'INT'未在此范围内声明

C和C ++中的枚举和范围规则是否不同?

2 个答案:

答案 0 :(得分:21)

在C中,枚举和结构的范围根本没有规则。您定义枚举的地方没有任何重要性。

在C ++中,在另一个东西中定义一些东西(比如类中的枚举)使这个东西属于另一个东西。

如果你想在c ++中使你的枚举全局化,你必须在你的类之外定义它,或者从你的struct路径访问:

#include <iostream>
struct mystruct
{
    enum {INT, FLOAT, STRING} type;
    int integer;
    float floating_point;
} tu;

int main()
{
    tu.type = mystruct::INT; // INT is not in global scope, I have to precise it.
    tu.integer = 100;
    return 0;
}

注意:这适用于此示例,因为您使用的是struct,默认情况下一切都为public。小心;只有当枚举位于public范围内时,您才可以从结构或类外部访问枚举类型和值,如任何字段或函数。

答案 1 :(得分:12)

主要区别在于与C相反,C ++有一个类范围。

在C中(6.2.1标识符范围)

  

4每个其他标识符的范围由其放置位置决定   声明(在声明者或类型说明符中)。如果是声明者或   声明标识符的类型说明符出现在any之外   块或参数列表,标识符有文件范围,其中   终止于翻译单元的末尾。

因此在这个程序中

#include <stdio.h>
struct mystruct
{
    enum {INT, FLOAT, STRING} type;
    int integer;
    float floating_point;
} tu;

/* Why is INT accessible here? */
int main()
{
    tu.type = INT;
    tu.integer = 100;
    return 0;
}

枚举器INT,FLOAT,STRING在任何块范围之外声明,因此具有文件范围。

在C ++中,定义了一个单独的范围 - 类范围:

3.3.7班级范围

  

1以下规则描述了在类中声明的名称范围。   1)在类中声明的名称的潜在范围不仅包括   名称的声明点后的声明区域,   而且所有函数体,默认参数,   异常规范,以及支持或等于初始化的   该类中的非静态数据成员(包括嵌套中的这些内容)   类)。

  

2 类成员的名称只能按如下方式使用:

     

- 在其类的范围内(如上所述)或派生的类   (第10条)来自其班级,

     

- 之后。运算符应用于其类型的表达式   class(5.2.5)或从其类派生的类

     

- 在 - &gt;之后运算符应用于指向其类对象的指针   (5.2.5)或从其类中派生的类

     

- 将:: scope resolution运算符(5.1)应用于名称之后   它的类或派生自其类的类。

考虑到(9.2班级成员)

  

1 ...班级成员是数据成员,成员函数(9.3),   嵌套类型和枚举器

因此在这个程序中

#include <iostream>
struct mystruct
{
    enum {INT, FLOAT, STRING} type;
    int integer;
    float floating_point;
} tu;

/* Why is INT accessible here? */
int main()
{
    tu.type = INT;  // Invalid access of class member
    tu.integer = 100;
    return 0;
}

您应该通过以下方式之一访问班级成员INT

    tu.type = mystruct::INT;

    tu.type = tu.INT;

甚至喜欢

    tu.type = ( &tu )->INT;