Programming Life

.NET World

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

通常我们会把一些相关的数值常量定义成一个enum类型,这样可以加强类型安全,同时使程序的可读性更强。进行.NET时代,一种公共类型系统中也定义了enum类型,但同时也增强了其功能,真正将其赋予了面向对象的特征,成为.NET中的第一等公民。但C++/CLI中允许托管代码和非托管代码共存,因此在使用中难免有些混淆。笔者试图从原理中加以剖析。

先看一个例子:

// MyEnum.cpp
// 标准C++中的enum声明
enum Color{Red, Blue, White};

// C++/CLI中的声明
enum class MColor1{Red,Blue,White};
enum struct MColor2{Red,Blue,White};
void main()
{
    
// 使用标准C++中的enum
    Color myColor0 = Red;

    
// 使用C++/CLI中的enum
    MColor1 myColor1 = MColor1::Blue;
    MColor2 myColor2 
= MColor2::White;

}

该程序只是简单地声明了enum类型,然后使用它。

在标准C++中只使用一个关键词enum,而在C++/CLI中则使用组合关键词如enum class

编译上面的程序(cl /clr:safe MyEnum.cpp),我们来检查生成的中间代码。

  
根据上图我们可以得出以下结论:

n         enum classenum struct是等价的。

n         三种类型都派生自System.Enum

n         每种类型都有一个内在数据类型。一般缺省是int,当然用户根据需要可以声明其他的数据类型,如果我声明下面的类型

 

enum class e1 : bool { Fail = false, Pass = true };

 

在中间代码中会是:

很显然这时的内在类型变成了bool

从图上矩形线框中我们也可看到有一点C++/CLI与传统的enum不同。托管类型的enum确实是生成了新的类型,我们称之为迭代子(enumerator)。正是这个原因,托管enum可以充分利用System.Enum的更多方法和属性。下面的代码就是枚举名称

   array<String^>^ names = Enum::GetNames(MColor1::typeid);

    
for each(String^ name in names)

    
{

        Console::WriteLine(name);
}


 
也正因为如此,传统的C++中,应该这样使用:

Color myColor0 = Red;

而不能这样:

Color myColor0 = Color::Red;

而且在上面的例子中,如下声明编译器会报“重定义”的错误:

enum Color{Red, Blue, White};

enum OtherColor{Red,Gray,Orange};// error C2365: 'Red' : redefinition;

而反观.NET中的枚举则无此限制,因为在使用中我们用了类型限制(如MColor1::)。

posted on 2008-07-06 11:17  许文科  阅读(3742)  评论(7编辑  收藏  举报