typedef'ing enum不会使枚举值可见

时间:2011-03-15 17:38:05

标签: c++ enums

我有一个类,我有一个枚举,定义如下:

class X
   {
   public:
      enum Direction {DIR_LEFT, DIR_RIGHT};
   };

现在我想要在另一个类中重用这个枚举,如下所示:

class Y
   {
   public:
      typedef X::Direction Direction;
   };

正如预期的那样,使用Y :: Direction可以正常工作,例如:

void myFunction (Y::Direction dir)
{
}

但枚举中的值似乎与typedef一起“复制”。如果我写下面的内容,我会收到编译错误:

myFunction (Y::DIR_LEFT);

相反,我必须再次引用枚举的原始位置,如下所示:

myFunction (X::DIR_LEFT);

这违背了我列举枚举的目的。

我看到的唯一解决方案是将枚举移出X类,并将其放在另一个类(例如MyEnums)中,因此它可以被X和Y重用(尽管它们仍然应该使用MyEnums :: DIR_LEFT和MyEnums :: DIR_RIGHT),但至少代码不再依赖于X类了。

为什么枚举值本身没有通过typedef公开?

是否有其他模式可以管理不同类中的枚举?

5 个答案:

答案 0 :(得分:14)

不幸的是,C ++没有引入一个带有enum的新作用域,尽管C ++ 0x正在改进。

实际上,这意味着您无法输入枚举枚举并获取枚举值。

可以做的是使用嵌套结构,其中包含enum和typedef THAT所需的名称。

class X
{
public:
    struct Direction { enum EnumType {LEFT, RIGHT}; };
};

class Y
{
public:
    typedef X::Direction Direction;
};

现在你可以这样做: myFunction (Y::Direction::LEFT);

嵌套结构的目的是创建一个“伪”范围来保存枚举名称及其值。

答案 1 :(得分:1)

以下是我对enums如何在C ++中工作的理解。 (或至少我在Microsoft Visual C ++中观察到的枚举行为。)

enum关键字不会像类那样创建范围。

然后您的枚举'Direction'的全名是X :: Direction。该枚举中的值仍然是类范围的一部分,因此它们是X :: DIR_LEFT和X :: DIR_RIGHT。

当你在另一个类中键入enum时,这不会改变枚举值的范围。

如果您想在多个位置共享枚举,我建议您将枚举放在头文件中的命名空间中。

答案 2 :(得分:1)

如果你想让枚举值成为两个类的成员,那么 解决方案是用枚举来定义一个单独的类,和 继承它,例如:

class MyEnums
{
protected:
    ~MyEnums() {} //  Prevent delete through pointer to this class
public:
    enum Direction
    {
        DIR_LEFT,
        DIR_RIGHT
    };
};

class X : public MyEnums
{
    // ...
};

class Y : public MyEnums
{
    // ...
};

用户将看到X :: Direction,X :: DIR_LEFT和Y :: Direction, Ÿ:: DIR_LEFT。当然,他们仍然能够通过 一个Y :: DIR_LEFT到一个期望X :: Direction的函数;至 防止这种情况,使MyEnums成为模板,派生类为 模板参数。

答案 3 :(得分:0)

多个类共享的任何内容都应该在类之外进行考虑,也许应该在父类中进行考虑。

direction.hpp:

#ifndef DIRECTION_HPP
enum Direction {DIR_LEFT, DIR_RIGHT};
#endif

x.hpp:

#ifndef X_HPP
#include "direction.hpp"

class X
{
  Direction dir;
};
#endif // X_HPP

y.hpp

#ifndef Y_HPP
#include "direction.hpp"

class Y
{
  Direction dir;
};
#endif // Y_HPP

答案 4 :(得分:0)

如果是原始声明:

    class X
    {
    public:
      enum Direction {DIR_LEFT, DIR_RIGHT};
    };

嵌入在一个大型遗留代码库中,然后我们可能需要一个的解决方案来改变X :: Direction的任何现有用法。在那种情况下,相当丑陋:

    class Y
    {
    public:
       typedef enum X::Direction Direction;
       static const enum X::Direction DIR_LEFT = X:DIR_LEFT;
       static const enum X::Direction DIR_RIGHT = X:DIR_RIGHT;
    }

工程...

然而,对于新代码,建议