Экземпляры шаблона класса ограничены предопределенными объектами - PullRequest
0 голосов
/ 15 октября 2018

Я хочу шаблон класса template<std::size_t N> Shape, где параметр шаблона N представляет измерение Shape.Должно быть ограниченное количество предопределенных Shape с, таких как Shape<2> SQUARE, Shape<3> CUBE и Shape<3> SPHERE.Я мог бы добавить больше предопределенных Shape в будущем.

Я хочу, чтобы Shape объекты могли быть конструируемыми только как любой из предопределенных Shape s.Поскольку свойства этих предопределенных Shape остаются неизменными во все времена, было бы оптимальным хранить их только один раз, а новые Shape объекты ссылаются на них.

В этот моментУ меня есть следующая реализация:

// Flag for the possible shapes
enum class Tag
{
    SPHERE,
    CUBE,
    SQUARE
};

template<std::size_t N>
class Shape
{
public:
    // Predefined shapes.
    static const Shape<3> SPHERE;
    static const Shape<3> CUBE;
    static const Shape<2> SQUARE;
    // Information stored about the given shapes
    const Tag tag; // tag specifying the shape
    const double v; // Shape volume/area
    const std::array<double, 2*N> surrounding_box; // Storing intervals for a surrounding box
    //... Some other information that depends on template parameter N
private:
    // Private constructor. This prevents other, unintended shapes from being created
    Shape(Tag tag, double v, const std::array<double, 2*N> surrounding_box):
            tag{tag}, v {v}, surrounding_box {surrounding_box} {};
};

// Initialization of predefined shape: SPHERE
template<std::size_t N>
const Shape<3> Shape<N>::SPHERE(Tag::SPHERE, 3.0,{{0.0,2.7,0.0,2.7,0.0,2.7}});

// Initialization of predefined shape: CUBE
template<std::size_t N>
const Shape<3> Shape<N>::CUBE(Tag::CUBE, 1.0,{{0.0,1.0,0.0,1.0,0.0,1.0}});

// Initialization of predefined shape: SQUARE
template<std::size_t N>
const Shape<2> Shape<N>::SQUARE(Tag::SQUARE, 1.0,{{0.0,1.0,0.0,1.0}});

Эта реализация имеет несколько проблем:

  • Каждый экземпляр Shape содержит все предопределенные Shape s (Как указано вкомментарии к этому вопросу );
  • Для каждого созданного экземпляра Shape копируется содержимое предопределенных Shape;
  • ДажеShape<3> объект содержит Shape<2> SQUARE.
  • ...

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

1 Ответ

0 голосов
/ 15 октября 2018

Заводская модель - это то, что вам нужно.Он делегирует создание экземпляров другому классу.

Существует несколько способов его реализации, вы можете выбрать уровень абстракции в зависимости от сложности вашей проблемы.

Вот базовый пример

template<std::size_t N>
class Shape
{
    friend class ShapeFactory;
public:
    // Information stored about the given shapes
    const Tag tag; // tag specifying the shape
    const double v; // Shape volume/area
    const std::array<double, 2*N> surrounding_box; // Storing intervals for a surrounding box
    //... Some other information that depends on template parameter N
private:
    // Private constructor. This prevents other, unintended shapes from being created
    Shape(Tag tag, double v, const std::array<double, 2*N> surrounding_box):
            tag{tag}, v {v}, surrounding_box {surrounding_box} {};
};

class ShapeFactory
{
public:
    // return value optimization
    static Shape<3> createSphere()
    {
        return Shape<3>(Tag::SPHERE, 3.0,{{0.0,2.7,0.0,2.7,0.0,2.7}});
    }

    static Shape<3> createCube()
    {
        return Shape<3>(Tag::CUBE, 1.0,{{0.0,1.0,0.0,1.0,0.0,1.0}});
    }

    static Shape<2> createSquare()
    {
        return Shape<2>(Tag::SQUARE, 1.0,{{0.0,1.0,0.0,1.0}});
    }
};

Поскольку свойства этих предопределенных фигур остаются неизменными в любое время, было бы оптимальным хранить их только один раз, а новые объекты Shape ссылаются на них.

если вы строго хотите использовать этот подход, вы можете обратиться к Prototype Pattern

...