Add example of visitor pattern in C++

This commit is contained in:
Shaun Reed 2021-05-11 20:56:05 -04:00
parent 53ee3df451
commit 8177d4c191
5 changed files with 132 additions and 0 deletions

View File

@ -23,3 +23,4 @@ add_subdirectory(prototype)
add_subdirectory(abstract-factory)
add_subdirectory(state)
add_subdirectory(observer)
add_subdirectory(visitor)

View File

@ -0,0 +1,20 @@
###############################################################################
## Author: Shaun Reed ##
## Legal: All Content (c) 2021 Shaun Reed, all rights reserved ##
## About: A project for practicing the visitor C++ design pattern ##
## ##
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
##############################################################################
#
cmake_minimum_required(VERSION 3.15)
project(
#[[NAME]] Visitor
VERSION 1.0
DESCRIPTION "An example of the visitor design pattern in C++"
LANGUAGES CXX
)
add_compile_options("-Wall")
add_library(visitor "visitor.cpp")
add_executable(visitor-test "main.cpp")
target_link_libraries(visitor-test visitor)

View File

@ -0,0 +1,16 @@
#include <iostream>
#include "visitor.hpp"
int main(const int argc, const char * argv[])
{
Gear *newGear = new Gear(1.5f, 1.0f);
PartVisitor *newVisitor = new PartVisitor;
// Test visiting the Gear concrete component with PartVisitor
newGear->accept(newVisitor);
// Testing a Spring concrete component on the same visitor
auto *newSpring = new Spring(2.5f, 5.0f);
newSpring->accept(newVisitor);
}

View File

@ -0,0 +1,32 @@
#include "visitor.hpp"
/******************************************************************************/
// Concrete components
void Gear::accept(PartVisitor *v)
{
v->visit(this);
}
void Spring::accept(PartVisitor *v)
{
v->visit(this);
}
/******************************************************************************/
// Concrete visitors
void PartVisitor::visit(Gear *g)
{
std::cout << g->getName() << " is price " << g->getPrice() << " with radius of "
<< g->getRadius() << std::endl;
}
void PartVisitor::visit(Spring *g)
{
std::cout << g->getName() << " is price " << g->getPrice()
<< " with elasticity of " << g->getElasticity() << std::endl;
}

View File

@ -0,0 +1,63 @@
#ifndef VISITOR_HPP
#define VISITOR_HPP
#include <string>
#include <iostream>
#include <utility>
class PartVisitor;
// Abstract component
class Part {
public:
Part(std::string name_, const float &price_) :
name(std::move(name_)), price(price_) {}
inline std::string getName() const { return name;}
inline float getPrice() const { return price;}
virtual void accept(PartVisitor *v) = 0;
private:
std::string name;
float price;
};
/******************************************************************************/
// Concrete components
class Gear : public Part {
public:
Gear(const float &price_, const float &radius_) :
Part("Gear", price_), radius(radius_) {}
void accept(PartVisitor *v) override;
inline float getRadius() const { return radius;}
private:
float radius;
};
class Spring : public Part {
public:
Spring(const float &price_, const float &elasticity_) :
Part("Spring", price_), elasticity(elasticity_) {}
void accept(PartVisitor *v) override;
inline float getElasticity() const { return elasticity;}
private:
float elasticity;
};
/******************************************************************************/
// Concrete visitors
class PartVisitor {
public:
// Handle visiting different components accordingly
virtual void visit(Gear *g);
virtual void visit(Spring *g);
};
#endif // VISITOR_HPP