【问题标题】:C++ Why am I unable to use an enum declared globally outside of the class it was declared in?C++ 为什么我不能使用在声明它的类之外全局声明的枚举?
【发布时间】:2011-02-22 15:04:48
【问题描述】:

现在,我的项目有两个类和一个主类。由于这两个类相互继承,因此它们都使用前向声明。在第一个对象中,在#include 语句的正下方,我在类定义之前初始化了两个枚举。我可以在该类中很好地使用这两个枚举。但是,如果我尝试在继承自第一个类的另一个类中使用这些枚举,则会收到错误消息,指出尚未声明枚举。如果我尝试在第二类中重新定义枚举,则会收到重新定义错误。

我什至尝试过使用我刚刚读到的技巧,并将每个枚举放在自己的命名空间中;这并没有改变任何东西。

这是一个例子:

#ifndef CLASSONE_H
#define CLASSONE_H

namespace Player
{
    enum Enum
    {
        One,
        Two,
    };
}

#endif

然后在第二个类中,我尝试使用之前声明的枚举:

void AddPlayer(Player::Enum playerNumber);

反而得到一个错误,说'Player'没有被声明。

【问题讨论】:

  • 你能给我们看一些简单的代码来证明这一点吗?
  • 第二类#包括“Classone.h”吗?
  • 是的,classone包括classtwo。
  • 为什么classone包括classtwo? #ifndef CLASSONE_H 的全部意义在于防止这种递归包含。基类标头应该包含在派生类标头中,因为派生类需要知道它是从什么派生的。基类不关心派生者是谁,所以你不需要在基类头中包含派生类头。
  • 你需要显示你所有的头文件。这在英语中来回是没有帮助的。这就是为什么我们有一种专门针对它的语言,它没有歧义。显示所有受影响的头文件的代码。

标签: c++ enums scope declaration


【解决方案1】:

如果没有看到您的代码,我不确定您遇到了什么问题,但这可以编译:

enum OutsideEnum
{
    OE_1,
    OE_2,
};

namespace ns
{
    enum NSEnum
    {
       NE_1,
       NE_2,
    };
}

class Base
{
public:
    enum BaseEnum
    {
        BE_1,
        BE_2,
    };

    void BaseFunc();
};

class Derived
{
public:
    enum DerivedEnum
    {
        DE_1,
        DE_2,
    };

    void DerivedFunc();
};

void Base::BaseFunc()
{
    BaseEnum be = BE_1;
    Derived::DerivedEnum de = Derived::DE_1;
    OutsideEnum oe = OE_1;
    ns::NEEnum ne = ns::NE_1;
}

void Derived::DerivedFunc()
{
    Base::BaseEnum be = Base::BE_1;
    DerivedEnum de = DE_1;
    OutsideEnum oe = OE_1;
    ns::NEEnum ne = ns::NE_1;
}

int main()
{
    Base::BaseEnum be = Base::BE_1;
    Derived::DerivedEnum de = Derived::DE_1;
    OutsideEnum oe = OE_1;
    ns::NEEnum ne = ns::NE_1;
}

在类定义中定义枚举需要注意两点:

  1. 如果您希望它公开可用,请确保它已声明为公开。
  2. 当从定义它的类以外的任何地方引用它时,使用类名来限定枚举的名称和值。

编辑:

好的,问题与枚举无关,而是包含顺序,当你有基类和派生类时,只有派生类需要知道基类:

基类头:

#ifndef BASE_H
#define BASE_H

enum BaseEnum
{
};

class Base
{
};
#endif

派生类头:

#ifndef DERIVED_H
#define DERIVED_H

#include "Base.h"

class Derived
{

   void Func(BaseEnum be);
};
#endif

【讨论】:

  • 明白了。问题是我在为它编写管理器之前编写了派生类,所以我在派生类的文件中声明了枚举,即使基类也需要它。我认为前向声明会是有序的,但事实并非如此。我能够通过删除#include“classtwo”并将枚举移动到基类来编译代码(同时保留前向声明,以便classone可以有一个classtwo的向量)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-28
  • 1970-01-01
  • 1970-01-01
  • 2018-09-09
  • 1970-01-01
  • 1970-01-01
  • 2011-01-09
相关资源
最近更新 更多