Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Enums поддерживает наследование

Автор вопроса: Christopher PiszОтветов: 2

Я часто сталкиваюсь с ситуацией, когда мы создаем класс, который воздействует на какое-то перечисление, но потом мы получаем его и хотим добавить в перечисление больше значений, не меняя базовый класс.

Я вижу этот вопрос из 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;
};
  • Нет, любые изменения перечисления с тех пор не имеют ничего общего с такого рода вещами. Kerrek SB 20.03.2017
  • Сильно ли изменился enum в 11-14-17? Я знаю, что они ввели строго типизированный enum class, но я почти уверен, что простой enum остается в основном таким же, как и всегда. ShadowRanger 20.03.2017

enumsc++17c++11c++14

Ответы

Ответ 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 ;
} ;

Но будьте осторожны: "мой самый большой страх - излишество ..." :) Мне бы не понравилась какая-то глубокая иерархия пространств имен с перечислениями в них и тому подобное ...

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы