为什么在C ++中声明枚举时使用typedef?
我已经多年没有编写任何C ++,现在我正试图回到它。 然后我跑过去,想着放弃:
typedef enum TokenType { blah1 = 0x00000000, blah2 = 0X01000000, blah3 = 0X02000000 } TokenType;
这是什么? 为什么在这里使用typedef
关键字? 为什么名称TokenType
在这个声明中出现两次? 语义如何不同于这个:
enum TokenType { blah1 = 0x00000000, blah2=0x01000000, blah3=0x02000000 };
在C中,声明你的枚举的第一种方式可以让你像这样使用它:
TokenType my_type;
如果你使用第二种风格,你将被迫像这样声明你的variables:
enum TokenType my_type;
正如其他人所说,这在C ++中没有什么不同。 我的猜测是,无论是写这篇文章的人都是C程序员,还是将C代码编译为C ++。 无论哪种方式,它不会影响您的代码的行为。
如果你这样做,这是一个C遗产,在C中:
enum TokenType { blah1 = 0x00000000, blah2 = 0X01000000, blah3 = 0X02000000 };
你将不得不使用它做一些事情:
enum TokenType foo;
但是,如果你这样做:
typedef enum e_TokenType { blah1 = 0x00000000, blah2 = 0X01000000, blah3 = 0X02000000 } TokenType;
你将能够声明:
TokenType foo;
但是在C ++中,只能使用前一个定义,并像使用C typedef一样使用它。
你不需要这样做。 在C(而不是C ++)中,您需要使用枚举枚举来引用枚举types的数据元素。 为了简化它,你被允许键入一个单一的名称数据types。
typedef enum MyEnum { //... } MyEnum;
允许将枚举的参数定义为的函数
void f( MyEnum x )
而不是更长的时间
void f( enum MyEnum x )
请注意,types名称的名称不需要等于枚举的名称。 结构也是如此。
另一方面,在C ++中,它不是必需的,因为枚举类,类和结构体可以按名称直接作为types来访问。
// C++ enum MyEnum { // ... }; void f( MyEnum x ); // Correct C++, Error in C
在C中,这是很好的风格,因为你可以改变types除了枚举之外的东西。
typedef enum e_TokenType { blah1 = 0x00000000, blah2 = 0X01000000, blah3 = 0X02000000 } TokenType; foo(enum e_TokenType token); /* this can only be passed as an enum */ foo(TokenType token); /* TokenType can be defined to something else later without changing this declaration */
在C ++中,您可以定义枚举,以便它可以编译为C ++或C
从C持有
“为什么”这个问题的实际答案(现有答案令人惊讶地被这个老问题所忽略)是这个enum
声明可能位于一个头文件中,这个头文件可以作为C和C ++代码交叉编译即包含在C和C ++实现文件中)。 编写这样的头文件的艺术依赖于作者select在两种语言中具有适当兼容含义的语言特征的能力。
有人说C没有命名空间,但这是不正确的。 它有三个:
-
enum
-
struct
- 全球(其他)
typedef enum { } XYZ;
声明一个匿名枚举并使用全局名称XYZ
将其导入到全局名称空间中。
typedef enum ABC { } XYZ;
在枚举名称空间中声明名为ABC
的枚举,然后将其作为XYZ
导入到全局名称空间中。
enum XYZ x;
在枚举名称空间中声明一个XYZ
types的variables。
所有这一切同样适用于struct命名空间。
有些人不想打扰单独的命名空间,所以他们键入一切。 其他人从来没有typedef,因为他们想要命名空间。
这是旧的,但是无论如何,我希望你们能够欣赏我今年早些时候遇到的这个链接。
在这里。 我应该引用我一直在想的解释,当我必须去掌握一些令人讨厌的typedef时:
在variables声明中,引入的名称是相应types的实例。 […]但是,当
typedef
关键字在声明之前时,引入的名称是相应types的别名
正如很多人以前所说,不需要在C ++中使用typedefs声明枚举。 但是这是typedef语法的解释! 我希望它有帮助(可能不是OP,因为已经差不多有10年了,但是任何人都在努力去理解这些东西)。
在一些C代码风格指南中,typedef版本被认为是“清晰”和“简单”的首选。 我不同意,因为typedef混淆了声明对象的真实性质。 实际上,我不使用typedef,因为当声明一个Cvariables时,我想清楚这个对象究竟是什么。 这个select可以帮助我更快地记住一段旧代码的实际做法,并且在未来维护代码时会帮助其他人。