为什么枚举值可以在用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 ++中的枚举和范围规则是否不同?
答案 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;