Я часто сталкиваюсь с ситуацией, когда мы создаем класс, который воздействует на какое-то перечисление, но потом мы получаем его и хотим добавить в перечисление больше значений, не меняя базовый класс.
Я вижу этот вопрос из 2009 года: Наследование базового класса enum
Однако я знаю, что в C++ 11, 14, 17 был внесен ряд изменений в перечисление. Позволяют ли какие-либо из этих изменений расширить перечисления из базового класса в производный?
class Base
{
enum State {STATE_1, STATE_2, STATE_3};
};
class Derived : public Base
{
enum State {STATE_4};
};
... где мы хотим, чтобы производное имело перечисление, описывающее состояния, в которых оно может находиться, а именно: СОСТОЯНИЕ_1, СОСТОЯНИЕ_2, СОСТОЯНИЕ_3 и СОСТОЯНИЕ_4. На самом деле мы не хотим менять перечисление в базовом классе, потому что другие производные классы могут не иметь возможности находиться в STATE_4. Мы также не хотим создавать новое перечисление, потому что у нас уже есть одно для состояния в базе.
Используем ли мы вместо этого статические значения const, чтобы добиться этого 8 лет спустя?
class Base
{
static int STATE_1= 0;
static int STATE_2= 1;
static int STATE_3= 2;
};
class Derived : public Base
{
static int STATE_4= 3;
};
Ответ 1 · рейтинг 6 · Nicol Bolas
Нет, С++ не допускает такого рода вещей. Base::Color - это совершенно отдельный тип от Derived::Color, никак не связанный с ними. Это ничем не отличается от любых других вложенных типов; вложенные типы, определенные в базовом классе, не связаны с вложенными типами, определенными в производном классе.
Перечисления также не могут наследоваться друг от друга.
Такого рода вещи в любом случае идут вразрез с хорошей практикой ООП. В конце концов, если производный класс вводит новый перечислитель, как с ним справится базовый класс? Как с этим справятся разные экземпляры производных классов?
Если Base определяет операцию над перечислением, то Base определяет совокупность перечисления, над которым оно работает, и каждый производный от него класс должен иметь возможность обрабатывать все эти параметры. В противном случае что-то не так с вашим виртуальным интерфейсом.
Ответ 2 · рейтинг 1 · Chef Gladiator
Почему бы просто не использовать пространства имен для группировки перечислений?
namespace my_codes {
enum class color { red, green, blue } ;
enum class origin { server, client } ;
} // my_codes
Использование может быть
struct my_signal {
my_codes::color flag ;
my_codes::origin source ;
} ;
Но будьте осторожны: "мой самый большой страх - излишество ..." :) Мне бы не понравилась какая-то глубокая иерархия пространств имен с перечислениями в них и тому подобное ...