Подтвердить что ты не робот

Наследование класса базового перечисления

Есть ли образец, где я могу наследовать перечисление от другого перечисления в C++??

Что-то вроде того:

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


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

Ответ 1

Невозможно. Наследования с перечислениями нет.

Вместо этого вы можете использовать классы с named const ints.

Пример:

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

#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;
}

Ответ 3

Вы не можете сделать это напрямую, но вы можете попробовать использовать решение из этой статьи.

Основная идея заключается в использовании вспомогательного класса шаблона, который содержит значения перечисления и имеет оператор приведения типа. Учитывая, что базовым типом для enum является int вы можете без проблем использовать этот класс-держатель в своем коде вместо enum.

Ответ 4

К сожалению, это невозможно в С++ 14. Надеюсь, у нас будет такая языковая функция в С++ 17. Поскольку у вас уже есть несколько обходных решений для вашей проблемы, я не буду предлагать решение.

Я хотел бы указать, что формулировка должна быть "расширением", а не "наследованием". Расширение допускает больше значений (поскольку вы переходите от 3 до 6 значений в вашем примере), тогда как наследование означает добавление большего количества ограничений к заданному базовому классу, поэтому набор возможностей сжимается. Следовательно, потенциальное кастинг будет работать в точности противоположно наследованию. Вы можете отличить производный класс к базовому классу, а не наоборот, с наследованием класса. Но когда вы имеете расширения, вы "должны" уметь применять базовый класс к его расширению, а не наоборот. Я говорю "должен", потому что, как я уже сказал, такой языковой функции по-прежнему не существует.

Ответ 5

Как насчет этого? Ок, экземпляр создается для каждого возможного значения, но, кроме того, он очень гибкий. Есть ли недостатки?

.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;
}

Ответ 6

Хорошо, если вы определите enum с тем же именем в производном классе и запустите его из последнего элемента корреспондента enum в базовом классе, вы получите почти то, что хотите - унаследованное перечисление. Посмотрите на этот код:

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

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

Ответ 7

Как указано bayda, перечисление не имеет функциональности (и/или не должно), поэтому я применил следующий подход к вашему затруднительному положению, адаптировав Mykola Golubyev response:

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

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

Ответ 8

Вы можете использовать проект 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

Ответ 9

невыполнима.
Но вы можете определить анонимное перечисление в классе, а затем добавить дополнительные константы перечисления в производные классы.

Ответ 10

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];