I was improving my visitor pattern code in c++ which originally looked like the code right below, in order to get rid of the unnecessary part where the visitor needs to pass itself to the accept void.
I came up with a simple solution which "turns" the parameter into a static field
so I can initialise the field right before I ever use accept
.
Forgive me but I need to do this even if it will be very ugly.
Old Code:
class A_Child;
class B_Child;
class Father {
public:
virtual ~Father() = default;
class Visitor {
public:
virtual void visitChildA(A_Child * child) = 0;
virtual void visitChildB(B_Child * child) = 0;
};
virtual void accept(Visitor * visitor) = 0;
};
class A_Child: public Father {
public: /* A Child Stuff */
void accept(Visitor * visitor) override;
};
class B_Child: public Father {
public: /* B Child Stuff */
void accept(Visitor * visitor) override;
};
A_Child::accept(Visitor * visitor) { visitor -> visitChildA(this); }
B_Child::accept(Visitor * visitor) { visitor -> visitChildB(this); }
New Code:
class Father {
public:
virtual ~Father() = default;
class Visitor {
public:
virtual void visitChildA(A_Child * child) = 0;
virtual void visitChildB(B_Child * child) = 0;
};
static Visitor * visitor;
virtual void accept() = 0;
};
// Outside, (assuming NewVisitor: public Father::Visitor):
void NewVisitor::DoStuff(Father * child) {
Father::visitor = this;
child -> accept();
}
Linker Complaints:
My linker is not happy about it and it gives me the following output:
Undefined symbols for architecture x86_64:
"Father::visitor", referenced from:
Child_A::accept() in Father.o
Child_B::accept() in Father.o
ld: symbol(s) not found for architecture x86_64
Does anyone know why is this happening? Am I breaking some mysterious OOP rule?