枚举成员与类名冲突

时间:2016-06-29 23:46:46

标签: c++ class enums abstract derived

我最近在处理一个小项目时产生了一系列错误的错误。这基本上是导致它的代码:

#include <memory>

enum derivedtype {B, C};

//abstract class
class A{};

class B : public A
{};
class C : public A
{};

int main()
{
  {
    std::unique_ptr<A> myb(new B);
    std::unique_ptr<A> myc(new C);
  }
}

产生此编译器错误:

enumclasserror.cpp: In function ‘int main()’:
  enumclasserror.cpp:15:30: error: ‘B’ does not name a type
  std::unique_ptr<A> myb(new B);
                          ^
  enumclasserror.cpp:16:30: error: ‘C’ does not name a type
  std::unique_ptr<A> myc(new C);

修复是在new:

之后添加class关键字
std::unique_ptr<A> myb(new class B);

现在enum被包含在原始代码中的abstact类的头文件中(这使得它更难发现),但是没关系;我原本无法想象枚举的成员会导致实例的创建失败。它花了我几个小时来找到那个bug。任何人都可以向我解释为什么会这样吗?新的内容对枚举有意义吗?

P.S。:使用clang建议使用class关键字的同事发现了这个错误。正如你所看到的,我的Ubuntu上的标准c ++编译器并没有... .. / / p>

2 个答案:

答案 0 :(得分:5)

在您的示例Benum隐藏了班级B。标准的第3.3.10节描述了名称隐藏的规则:

  

类名(9.1)或枚举名(7.2)可以通过在同一范围内声明的变量,数据成员,函数或枚举器的名称隐藏。如果类或枚举名称和变量,数据成员,函数或枚举器在同一作用域(按任何顺序)中声明具有相同名称,则类或枚举名称将隐藏在变量,数据成员,函数或枚举器名称可见。

语言设计者需要设置优先级规则,因此他们决定enum常量名称应该获胜。这条规则似乎是随意的,可能是在C标准中的一些旧规则之后建模的。但是,它是标准的一部分,因此每个编译器都必须遵守它。

不言而喻,让一个类名与enum成员发生碰撞是一个非常糟糕的主意。解决此问题的最佳方法是重命名您的课程。

答案 1 :(得分:2)

我不确定你在这里还有什么预期。

首先,您引入了名为BC的整数常量。当然,你不能new这些。这就像写new 42

然后,您引入了具有相同名称的类型。好的,很好,这是允许的,但为了使用它们,您现在必须将它们称为class Bclass C(或struct Bstruct C),正如你所发现的那样。

不要对不同的东西使用相同的名称。