Возможные реализации для решения конкретных задач
Visitor
Посетитель с приведением типа между базовыми классами
Реализация посетителя с приведением типа между базовыми классами использует пустой абстрактный класс посетителя, который дополняется посетителями конкретных типов при помощи реализации идиомы MixIn.
Подход может быть использован, в случае, если требуется создавать посетители с сильно разнящимся поведением относительно посещаемых типов, когда мы не хотим размещать разную логику обработки сущностей рядом в одном классе.
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
int main()
{
shared_ptr<Shape> figure = make_shared<Figure>(
initializer_list<shared_ptr<Shape>>(
{ make_shared<Circle>(1), make_shared<Square>(2) }
)
);
figure->accept(Draw{});
}
Посетитель с использованием шаблона variant ("безопасный" union)
#include <iostream>
#include <vector>
#include <variant>
using namespace std;
int main()
{
using Shapes = vector<Shape>;
Shapes fiqure = Formation::initialization({ Circle{}, Square{} });
for (const auto& elem : fiqure)
std::visit(Draw{}, elem);
}
Шаблонный посетитель (Template visitor) с использованием паттерна CRTP (Curiously Recurring Template Pattern)
Реализация шаблонного посетителя прибегает к вариативным шаблонам классов для определения типа посетителя, который посещает заданные классы. За счёт использования CRTP можно избавиться от реализации метода accept в каждой сущности, перенеся ответственность за это на класс Visitable.
# include <iostream>
# include <memory>
# include <initializer_list>
# include <vector>
using namespace std;
int main()
{
Point p;
shared_ptr<Composite> figure = make_shared<Composite>(
initializer_list<shared_ptr<Shape>>(
{ make_shared<Figure>(p), make_shared<Camera>(p), make_shared<Figure>(p) }
)
);
shared_ptr<ShapeVisitor> visitor = make_shared<DrawVisitor>();
figure->accept(visitor);
}
Last updated
Was this helpful?