Присоединяясь к полиморфному списку в C ++? - PullRequest
0 голосов
/ 29 апреля 2019

Я новичок в C ++ и пытаюсь сделать список полиморфным / принимая все, что происходит от базового класса.Проблема в том, что этот список должен быть закрытым, с использованием отдельных методов для его добавления и опроса.

После некоторых исследований мне удалось безопасно приблизиться с помощью умных указателей.

Здесьвот к чему я пришел:

class Shape
{
public:
    Shape(std::string name)
    {
        this->name = name;
    }

    std::string name;
    std::string getName(void)
    {
        return this->name;
    }
};

class ShapeCollector
{
public:
    void addShape(Shape shape)
    {
        this->shapes.push_back(std::make_unique<Shape>("hey"));
    }

private:
    std::vector <std::unique_ptr<Shape>> shapes;
};

Я хотел бы иметь возможность заменить вызов make_unique параметром shape, однако, похоже, все, что я пытаюсь сделать, работает неправильно.

Я мог бы создатькаждый производный класс внутри ShapeCollector, зеркально отображающий аргументы конструктора в качестве параметров, но это кажется очень интуитивно понятным.

Любая помощь приветствуется!

1 Ответ

3 голосов
/ 29 апреля 2019

Введите addShape, чтобы взять производный класс в качестве параметра шаблона:

template<class Derived, class... Args>
void addShape(Args&&... args) {
    // std::forward will correctly choose when to copy or move
    std::unique_ptr<Shape> shape (new Derived(std::forward<Args>(args)...));
    shapes.push_back(std::move(shape)); 
}

Это позволит вам addShape указать аргументы для производного класса s constructor. For example, if we have a Circle` class:

class Circle : public Shape {
    double radius;
    double x;
    double y;
   public:
    Circle(double radius, double x, double y) 
      : Shape("circle"), radius(radius), x(x), y(y) 
    {}
};

Добавить это просто:

ShapeCollector shapes;
shapes.addShape<Circle>(10.0, 0.0, 0.0); 
...