Расширение перечислений в C++?
есть ли способ в C++ расширить / "наследовать" перечисления?
То Есть:
enum Enum {A,B,C};
enum EnumEx : public Enum {D,E,F};
или хотя бы определить преобразование между ними?
6 ответов:
нет, нет.
enum
действительно бедная вещь в C++, и это, конечно, печально.даже
class enum
введенный в C++0x не решает эту проблему расширяемости (хотя они делают некоторые вещи для безопасности типа по крайней мере).единственное преимущество
enum
Это то, что они не существуют: они предлагают некоторую безопасность типа, не накладывая никаких накладных расходов во время выполнения, поскольку они заменяются компилятором напрямую.если вы хотите такой зверь, тебе придется работать самому:
- создать класс
MyEnum
, который содержит int (в основном)- создать именованные конструкторы для каждого из интересных значений
теперь вы можете расширить свой класс (добавление именованных конструкторов) по желанию...
это обходной путь, хотя я никогда не находил удовлетворительный способ работы с перечислением...
Если бы вы смогли создать подкласс перечисления, он должен был бы работать наоборот.
набор экземпляров в подклассе является подмножество из экземпляров в супер-классе. Подумайте о стандартном примере "формы". Класс Shape представляет собой набор всех фигур. Класс Circle, его подкласс, представляет подмножество фигур, которые являются кругами.
таким образом, чтобы быть последовательным, подкласс перечисления должен содержать подмножество элементов в перечислении он наследует от.
(и нет, C++ не поддерживает это.)
Я решил таким образом:
typedef enum { #include "NetProtocols.def" } eNetProtocols, eNP;
конечно, если вы добавляете новый сетевой протокол в NetProtocols.def файл, вы должны перекомпилировать, но по крайней мере он расширяется.
http://www.codeproject.com/KB/cpp/InheritEnum.aspx переходит к методу для создания расширенного перечисления.
просто мысль:
вы можете попытаться создать пустой класс для каждой константы (возможно, поместить их все в один и тот же файл, чтобы уменьшить беспорядок), создать один экземпляр каждого класса и использовать указатели на эти экземпляры в качестве "констант". Таким образом, компилятор поймет наследование и выполнит любое преобразование ChildPointer-to-ParentPointer, необходимое при использовании вызовов функций, и вы все равно получите проверки безопасности типа компилятором, чтобы убедиться, что никто не передает недопустимое значение int к функциям (которые должны использоваться, если вы используете метод последнего значения для "расширения" перечисления).
не полностью продумали это, хотя так что любые комментарии по этому подходу приветствуются.
и я постараюсь опубликовать пример того, что я имею в виду, как только у меня будет некоторое время.