枚举和前置声明以及可能引起的问题

 在VC++ 2008下编译如下代码:

void  func( enum  EnumType type)
{
    
// ......
}
int  main()
{
    EnumType type  =  (EnumType) 0 ;
    func(type);
    
return   0 ;
}

你会发现这段代码可以成功的编译并且运行,但是如果你足够细心,应该会发现EnumType并没有被定义,为什么使用没有定义的类型却能正常编译甚至运行呢?

原因有二: 

1. 函数中的参数声明enum EnumType type,不但被解析为一个参数声明,也被解析为对EnumType的一个前置声明。
其实不光对enum,对class也是一样,比如
void  func( class  Base b)
{
    
// ......
}

也是没有问题的,这里在声明函数参数的同时,因为加了class这个关键词,也达到了前置声明calss Base的效果。

2. VC++的扩展对enum的前置声明的支持。
我们知道,C++标准其实是不支持enum的前置声明的,原因在于标准规定Enum的size是由其所容纳的值所确定的,所以在看到所有的值之前,编译器是无法确定其存储的。在这篇讨论中可以得到很多信息。而在VC++实现中,确定enum的size为4个字节,从而使Enum的前置声明成为可能 --- 不得不说,我认为这是VC++不同于标准,却又高于标准的实现。

所以以上代码其实是前置声明并使用了EnumType,因为并没有设计到EnumType的具体的枚举值,所以使用并没有任何问题 --- 毕竟,Enum是个4字节的整型数而已。

我们知道,在C中,当我们使用一个定义好的enum时(struct也一样),我们需要在定义的类型前加上前缀enum ,而不是直接使用该类型,比如前面的EnumType, 我们应该以enum EnumType的方式来使用,但在C++中,这个限制不再存在,但是这种用法被保留了下来。所以我们可以看到在不少地方大家还是会这么用。这就为引入问题提供了方便:

你以为你在使用你定义的那个enum,其实你只是在使用你自己前置声明的那个而已


 举个我在现实项目中遇到的问题,看如下代码:

 1  class  Scope
 2  {
 3  public :
 4       enum  EnumType {kType1, kType2};
 5  };
 6 
 7  class  Base
 8  {
 9  public :
10       virtual   void  Func( enum Scope::EnumType type){}
11  };
12 
13  class  Derived:  public  Base
14  {
15  public :
16       virtual   void  Func( enum  EnumType type)
17      {
18           //  Compiler can't catch the error even you compare 2 different enum types
19           if (type  ==  Scope::kType1)  return ;
20      }
21  };
22 
23  int  main()
24  {
25      Scope::EnumType type  =  Scope::kType1;
26      Base *  pBase  =   new  Derived();
27      pBase -> Func(type);
         delete pBase;

28     return 0;
29}

 

这里试图在Derived中重载Base中的Func虚函数, 但是在声明参数的时候用了enum EnumType,而不是enum Scope::EnumType,而编译器不会报错。但事实上, 这里是直接前置声明了一个与Scope::EnumType截然不同的枚举类型EnumType,结果是Derived::Func永远也不会被调到,因为它根本就不是个虚函数Base::Func的重载。

了解了这些,我的对使用Enum的建议是:

 

  1. 在C++中使用enum时,最好直接用类型名,而不是像C中那样加个enum的前缀,主要是放了防止意外的前置声明。
  2. VC++中的enum的前置声明是个好东西,应该加以利用 ,但使用时要显示的来用。 

 

 

转载于:https://www.cnblogs.com/baiyanhuang/archive/2010/10/16/1853072.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值