基本枚举类继承

时间:2009-03-13 21:03:03

标签: c++ enums

是否有一种模式可以从C ++中的另一个枚举继承枚举?

类似的东西:

enum eBase 
{
   one=1, two, three
};


enum eDerived: public eBase
{
   four=4, five, six
};

12 个答案:

答案 0 :(得分:88)

#include <iostream>
#include <ostream>

class Enum
{
public:
    enum
    {
        One = 1,
        Two,
        Last
    };
};

class EnumDeriv : public Enum
{
public:
    enum
    {
        Three = Enum::Last,
        Four,
        Five
    };
};

int main()
{
    std::cout << EnumDeriv::One << std::endl;
    std::cout << EnumDeriv::Four << std::endl;
    return 0;
}

答案 1 :(得分:58)

不可能。枚举没有继承。

您可以改为使用名为const int的类。

示例:

class Colors
{
public:
  static const int RED = 1;
  static const int GREEN = 2;
};

class RGB : public Colors
{
  static const int BLUE = 10;
};


class FourColors : public Colors
{
public:
  static const int ORANGE = 100;
  static const int PURPLE = 101;
};

答案 2 :(得分:10)

您无法直接执行此操作,但您可以尝试使用this文章中的解决方案。

主要思想是使用包含枚举值的helper模板类,并具有类型强制转换操作符。考虑到枚举的基础类型为int,您可以在代码中无缝地使用此持有者类而不是枚举。

答案 3 :(得分:5)

不幸的是,在C ++ 14中是不可能的。我希望我们在C ++ 17中有这样的语言功能。由于您已经为您的问题找到了一些解决方法,因此我无法提供解决方案。

我想指出的措辞应该是&#34;扩展&#34;不是&#34;继承&#34;。扩展允许更多的值(因为您在示例中从3跳到6个值),而继承意味着将更多约束放到给定的基类中,因此可能性会缩小。因此,潜在的铸造将与继承完全相反。您可以将派生类强制转换为基类,而不是反过来继承类继承。但是当你有扩展时,你应该&#34;能够将基类强制转换为其扩展而不是反之。我说&#34;应该&#34;因为,正如我所说,这样的语言特征仍然不存在。

答案 4 :(得分:3)

这个怎么样?确定为每个可能的值创建一个实例,但除此之外它非常灵活。有没有缺点?

<强>·H

class BaseEnum
{
public:
  static const BaseEnum ONE;
  static const BaseEnum TWO;

  bool operator==(const BaseEnum& other);

protected:
  BaseEnum() : i(maxI++) {}
  const int i;
  static int maxI;
};

class DerivedEnum : public BaseEnum
{
public:
  static const DerivedEnum THREE;
};

<强>的.cpp:

int BaseEnum::maxI = 0;

bool BaseEnum::operator==(const BaseEnum& other) {
  return i == other.i;
}

const BaseEnum BaseEnum::ONE;
const BaseEnum BaseEnum::TWO;
const DerivedEnum DerivedEnum::THREE;

<强>用法:

BaseEnum e = DerivedEnum::THREE;

if (e == DerivedEnum::THREE) {
    std::cerr << "equal" << std::endl;
}

答案 5 :(得分:2)

好吧,如果你在派生类中定义enum同名,并从基类中对应的enum的最后一项开始,你几乎会得到你想要的东西 - 继承的枚举。 看看这段代码:

class Base
{
public:
enum ErrorType
  {
  GeneralError,
  NoMemory,
  FileNotFound,
  LastItem
  }
}

class Inherited: public Base
{
enum ErrorType
  {
  SocketError = Base::LastItem,
  NotEnoughBandwidth,
  }
}

答案 6 :(得分:2)

bayda所述,enum不会(和/或不应该)具有功能,因此我通过调整Mykola Golubyev的响应采取了以下方法来解决您的困境:< / p>

typedef struct
{
    enum
    {
        ONE = 1,
        TWO,
        LAST
    };
}BaseEnum;

typedef struct : public BaseEnum
{
    enum
    {
        THREE = BaseEnum::LAST,
        FOUR,
        FIVE
    };
}DerivedEnum;

答案 7 :(得分:2)

您可以使用项目SuperEnum创建可扩展的枚举。

/*** my_enum.h ***/
class MyEnum: public SuperEnum<MyEnum>
{
public:
    MyEnum() {}
    explicit MyEnum(const int &value): SuperEnum(value) {}

    static const MyEnum element1;
    static const MyEnum element2;
    static const MyEnum element3;
};

/*** my_enum.cpp ***/
const MyEnum MyEnum::element1(1);
const MyEnum MyEnum::element2;
const MyEnum MyEnum::element3;

/*** my_enum2.h ***/
class MyEnum2: public MyEnum
{
public:
    MyEnum2() {}
    explicit MyEnum2(const int &value): MyEnum(value) {}

    static const MyEnum2 element4;
    static const MyEnum2 element5;
};

/*** my_enum2.cpp ***/
const MyEnum2 MyEnum2::element4;
const MyEnum2 MyEnum2::element5;

/*** main.cpp ***/
std::cout << MyEnum2::element3;
// Output: 3

答案 8 :(得分:1)

此答案是Brian R. Bondy答案的变体。由于已在评论中被请求,因此我将其添加为答案。我并不是要指出是否真的值得。

#include <iostream>

class Colors
{
public:
    static Colors RED;
    static Colors GREEN;

    operator int(){ return value; }
    operator int() const{ return value; }

protected:
    Colors(int v) : value{v}{} 

private:
    int value;
};

Colors Colors::RED{1};
Colors Colors::GREEN{2};

class RGB : public Colors
{
public:
    static RGB BLUE;

private:
    RGB(int v) : Colors(v){}
};

RGB RGB::BLUE{10};

int main ()
{
  std::cout << Colors::RED << " " << RGB::RED << std::endl;
}

Live at Coliru

答案 9 :(得分:0)

不可能。
但是你可以在类中匿名定义枚举,然后在派生类中添加额外的枚举常量。

答案 10 :(得分:0)

有点骇人听闻,但这是我在处理作用域枚举时想到的:

enum class OriginalType {
   FOO,  // 0
   BAR   // 1
   END   // 2
};

enum class ExtendOriginalType : std::underlying_type_t<OriginalType> {
   EXTENDED_FOO = static_cast<std::underlying_type_t<OriginalType>>
                                           (OriginalType::END), // 2
   EXTENDED_BAR  // 3
};

然后使用类似:

OriginalType myOriginalType = (OriginalType)ExtendOriginalType::EXTENDED_BAR;

答案 11 :(得分:-1)

enum xx {
   ONE = 1,
   TWO,
   xx_Done
};

enum yy {
   THREE = xx_Done,
   FOUR,
};

typedef int myenum;

static map<myenum,string>& mymap() {
   static map<myenum,string> statmap;
   statmap[ONE] = "One";
   statmap[TWO] = "Two";
   statmap[THREE] = "Three";
   statmap[FOUR] = "Four";
   return statmap;
}

用法:

std::string s1 = mamap()[ONE];
std::string s4 = mymap()[FOUR];