#include <iostream>
#include <memory>
class ConcreteComponent1;
class ConcreteComponent2;
class Visitor {
public:
virtual void visitconcretecomponent1(ConcreteComponent1 *cc1) = 0;
virtual void visitconcretecomponent2(ConcreteComponent2 *cc2) = 0;
};
class Component {
public:
virtual void accept(std::shared_ptr<Visitor> v) = 0;
};
class ConcreteComponent1 : public Component {
public:
void accept(std::shared_ptr<Visitor> cv) {
cv->visitconcretecomponent1(this);
}
int data1() { return 1; }
std::string data2() { return "2"; }
};
class ConcreteComponent2 : public Component {
public:
void accept(std::shared_ptr<Visitor> cv) {
cv->visitconcretecomponent2(this);
}
int data1() { return 3; }
std::string data2() { return "4"; }
};
class ConcreteVisitor1 : public Visitor {
public:
void visitconcretecomponent1(ConcreteComponent1 *cc) override {
std::cout << "In ConcreteVisitor1 visitconcretecomponent1. The data1 is " << cc->data1() << std::endl;
std::cout << "In ConcreteVisitor1 visitconcretecomponent1. The data2 is " << cc->data2() << std::endl;
}
void visitconcretecomponent2(ConcreteComponent2 *cc) override {
std::cout << "In ConcreteVisitor1 visitconcretecomponent2. The data1 is " << cc->data1() << std::endl;
std::cout << "In ConcreteVisitor1 visitconcretecomponent2. The data2 is " << cc->data2() << std::endl;
}
};
class ConcreteVisitor2 : public Visitor {
public:
void visitconcretecomponent1(ConcreteComponent1 *cc) override {
std::cout << "In ConcreteVisitor2 visitconcretecomponent1. The data2 is " << cc->data2() << std::endl;
std::cout << "In ConcreteVisitor2 visitconcretecomponent1. The data1 is " << cc->data1() << std::endl;
}
void visitconcretecomponent2(ConcreteComponent2 *cc) override {
std::cout << "In ConcreteVisitor2 visitconcretecomponent2. The data2 is " << cc->data2() << std::endl;
std::cout << "In ConcreteVisitor2 visitconcretecomponent2. The data1 is " << cc->data1() << std::endl;
}
};
int main(int argc, char *argv[]) {
std::shared_ptr<Component> cc1 = std::make_shared<ConcreteComponent1>();
std::shared_ptr<Component> cc2 = std::make_shared<ConcreteComponent2>();
std::shared_ptr<Visitor> v1 = std::make_shared<ConcreteVisitor1>();
std::shared_ptr<Visitor> v2 = std::make_shared<ConcreteVisitor2>();
cc1->accept(v1);
cc2->accept(v2);
return 1;
}