Ну, вы используете имя класса enum точно так же, как и имя любого другого обычного класса, например,
Ball_colors m_color;
в качестве члена класса. Однако, поскольку цвета и размеры тесно связаны с самим мячом, я бы вложил определение в класс Ball
. Затем вы также можете удалить префикс:
class Ball
{
enum class Color { /*...*/ };
enum class Size { /* ... */ };
Color m_color;
Size m_size;
};
И я исключил бы множественное число из имени, это выглядит не так уж и элегантно, если указать тип члена во множественном числе, который может представлять только один value ...
Если вам нужно использовать перечисления снаружи, вы можете обращаться к ним как
Ball::Color::red
Теперь каждая запись перечисления получает определенное значение c, начиная с 0 для первого один и каждый последующий увеличивается на единицу (если вы явно не указали значения для некоторых или всех записей). Затем вы можете использовать генератор случайных чисел для получения значения в соответствующем диапазоне и приведения этого значения обратно к перечислению, например:
class Ball
{
static inline std::mt19937 s_generator { std::random_device()() };
template <typename T>
static T get()
{
std::uniform_int_distribution<std::underlying_type_t<T>> d
(
0, static_cast<std::underlying_type_t<T>>(T::Max) - 1
);
return static_cast<T>(d(s_generator));
}
public:
Ball()
: m_color(get<Color>()),
m_size(get<Size>())
{ }
};
Выше предполагается, что вы добавили значение стража Max
к обоим перечислениям ( после всех остальных записей); в качестве альтернативы, вы также можете передать максимально допустимое значение в функцию шаблона, тогда вам не нужно указывать параметр шаблона:
template <typename T>
static T get(T max)
{
std::uniform_int_distribution<std::underlying_type_t<T>> d
(
0, static_cast<std::underlying_type_t<T>>(max)
);
return static_cast<T>(d(s_generator));
}
Ball()
: m_color(get(Color::green))
// ...
Но вам придется следить за этим вторым местоположением за возможность адаптации, если вы добавите дополнительные значения в перечисление!