Skip to content

Commit 27428a0

Browse files
committed
^Visitor
1 parent 7bd5a97 commit 27428a0

File tree

1 file changed

+34
-24
lines changed

1 file changed

+34
-24
lines changed

cpp/patterns.cpp

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -427,16 +427,13 @@ struct Command
427427

428428
/**
429429
@defgroup visitor Visitor
430+
@brief [Visitor pattern](https://en.wikipedia.org/wiki/Visitor_pattern)
431+
432+
https://refactoring.guru/design-patterns/visitor/cpp/example
430433
@{
431434
*/
432435

433-
struct Visitor
434-
/// @brief is a pure virtual visitor of Sample_component and other specific components
435-
{
436-
struct Sample_component;
437-
virtual string visit(const Sample_component&) const = 0;
438-
virtual ~Visitor() = default;
439-
};
436+
struct Visitor;
440437

441438
struct Component
442439
/// @brief accepts a pure virtual Visitor
@@ -445,22 +442,20 @@ struct Component
445442
virtual ~Component() = default;
446443
};
447444

448-
string client_visit(const forward_list<unique_ptr<Component>>& components,
449-
Visitor& visitor)
450-
/// @brief knows only virtual visitor and component
445+
struct Sample_component;
446+
struct Visitor
447+
/// @brief is a pure virtual visitor of Sample_component and other specific components
451448
{
452-
string res;
453-
for (auto&& comp : components) {
454-
res += string(__func__) + " > " + comp->component_accept(visitor);
455-
//assert(rc);
456-
}
457-
//assert(rc);
458-
return res;
459-
}
449+
/// overloaded function for each component
450+
virtual string visit(const Sample_component&) const = 0;
451+
virtual ~Visitor() = default;
452+
};
460453

461-
struct Visitor::Sample_component
454+
struct Sample_component
462455
: public Component
463-
/// @brief one of many components
456+
/** @brief one of many components
457+
is independent from Sample_visitor and implementations of function visit.
458+
*/
464459
{
465460
string component_accept(Visitor& visitor) const override {
466461
return string(__func__) + " > " + visitor.visit(*this);
@@ -471,6 +466,18 @@ struct Visitor::Sample_component
471466
}
472467
};
473468

469+
string client_visit(const forward_list<unique_ptr<Component>>& components,
470+
const forward_list<unique_ptr<Visitor>>& visitors)
471+
/// @brief knows only virtual visitor and component
472+
{
473+
string res;
474+
for (auto&& comp : components)
475+
for (auto&& vis : visitors) {
476+
res += string(__func__) + " > " + comp->component_accept(*vis.get());
477+
}
478+
return res;
479+
}
480+
474481
/**
475482
Call hierarchy:
476483
@@ -487,16 +494,19 @@ void visitor_demo()
487494
/// Per each of the possible pairs of Sample_visitor and Sample_component
488495
struct Sample_visitor
489496
: public Visitor {
490-
string visit(const Visitor::Sample_component& c) const override {
497+
/// overloaded function for each component
498+
string visit(const Sample_component& c) const override {
491499
return string(__func__) + " > " + c.component_method();
492500
}
493501
};
494502

495503
forward_list<unique_ptr<Component>> components;
496-
components.emplace_front(new Visitor::Sample_component);
504+
components.emplace_front(new Sample_component);
497505
Sample_visitor v;
498-
assert(client_visit(components, v) ==
499-
"client_visit > component_accept > visit > component_method");
506+
forward_list<unique_ptr<Visitor>> visitors;
507+
visitors.emplace_front(new Sample_visitor);
508+
assert(client_visit(components, visitors) ==
509+
"client_visit > component_accept > visit > component_method");
500510
}
501511

502512
/// @} visitor

0 commit comments

Comments
 (0)