mardi 24 août 2021

Is it possible for a visitor in c++ to operate over multiple projects?

I'm trying to add a visitor to an existing library. The visitor must be able to visit some classes from separate projects.

Let's say my solution have the following projects: ProjectA, ProjectB and they contain 1 class each respectively: NodeA, NodeB. Since the visitor is only an implementation of a class member outside of the class, I think its dependency won't allow it to be placed at another project. So if I want to create a visitor which can visit both NodeA and NodeB objects, I can't use a simple visitor.

Is this assessment correct?

I was thinking about a couple of solutions to overcome this.

  1. Move one the classes to the other projectand implement visitor there (this isnot a feasible solution).
  2. Add an extra indirection. Create a class for the visitor implementation for each project. And create a "head visitor" which would use these implementation objects.

Am I missing something? Is there a better way to do this?

Please find my visitor implementation below. Please note that I removed header guards for the sake of simplicity.

/// --- Node.h in project A ---
class Visitor;

class Node {
  public:
    Node() = default;
    virtual ~Node() = default;
    virtual void accept(Visitor & v) = 0;
};

/// --- NodeA.h  in project A ---
#include "Visitor.h"

class NodeA : public Node {
public:
    void accept(Visitor & v);
};

/// --- NodeB.h  in project B ---
#include "Visitor.h"

class NodeB : public Node {
public:
    void accept(Visitor & v);
};

/// --- Visitor.h ---
#include "Node.h"

class NodeA;
class NodeB;

class Visitor {
  public:
    Visitor() = default;
    virtual ~Visitor() = default;

    virtual void visit(const Node & node) = 0;
    virtual void visit(const NodeA & node) = 0;
    virtual void visit(const NodeB & node) = 0;
};

// --- Visitor.cpp (includes B.hpp and C.hpp) ---

#include "Visitor.h"
#include "NodeA.h"

void Visitor::visit(const Node & node)
{
   // implementation
}

void Visitor::visit(const NodeA & node)
{
   // implementation
}

void Visitor::visit(const NodeB & node)
{
   // implementation
}


Aucun commentaire:

Enregistrer un commentaire