Использование класса Enum для определения членов класса - PullRequest
0 голосов
/ 21 января 2020

Для задания, над которым я работаю, мне нужно создать перечислимые классы и использовать их для определения членов другого класса. Перечисляются следующие классы:

enum class Ball_colors {
    red,
    blue,
    yellow,
    green
};

enum class Ball_sizes {
    small,
    medium,
    large
};

Класс, называемый «шар», представляет собой шар определенного цвета и размера. Предполагается, что конструктор по умолчанию для шара выбирает цвет и размер случайным образом. Предполагается, что у меня есть параметризованный конструктор и функции для получения размера или цвета, но я понятия не имею, как использовать классы enum, особенно в других классах. , Я даже не уверен, что правильно определил классы. Как я могу использовать классы enum в другом классе и как я могу случайно выбрать что-то из класса enum?

Ответы [ 3 ]

1 голос
/ 21 января 2020

Ну, вы используете имя класса 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))
    // ...

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

0 голосов
/ 21 января 2020

Вы можете определить члены данных класса типа перечисляемого класса так же, как вы определяете другие члены данных класса.

Вот демонстрационная программа.

#include <iostream>
#include <string>

enum class Ball_colors {
    red,
    blue,
    yellow,
    green
};

enum class Ball_sizes {
    small,
    medium,
    large
};

class Ball
{
private:
    Ball_colors color = Ball_colors::red;
    Ball_sizes size = Ball_sizes::small;

public:
    Ball() = default;
    Ball( Ball_colors color, Ball_sizes size ) : color( color ), size( size )
    {
    }

    std::string to_string() const
    {
        const char *string_colors[] = { "red", "blue", "yellow", "green" };
        const char *string_sizes[]  = { "small", "medium", "large" };

        std::string s( "The ball is " );
        return s + string_sizes[static_cast<size_t>( size )] + 
               " and " + string_colors[static_cast<size_t>( color )] + ".";
    }
};

int main() 
{
    Ball ball1;

    std::cout << ball1.to_string() << '\n';

    Ball ball2( Ball_colors::blue, Ball_sizes::large );

    std::cout << ball2.to_string() << '\n';

    return 0;
}

Его выход

The ball is small and red.
The ball is large and blue.
0 голосов
/ 21 января 2020

Просто есть что-то вроде:

struct Ball
{
    Ball_colors color = Ball_colors::red;
    Ball_sizes size = Ball_sizes::small;

    Ball(Ball_colors color, Ball_sizes size) : color(color), size(size) {}
};
...