I'm implementing the Visitor pattern, and I have an accept() function that is only defined in the base visitable class. This system works just fine, but Alexandresku states in his book that the this pointer has static typing.
Is this code flawed and/or has a bug, but my output is not catching it?
I have tried to change references to pointers, but the output does not change.
.h file
class WidgetVisitor
{
public:
virtual void visit(ConcreteWidget1& w1);
virtual void visit(ConcreteWidget2& w2);
virtual void visit(Widget& w);
virtual ~WidgetVisitor() { }
};
class Widget
{
public:
Widget(const std::string& text);
virtual std::string text() const;
virtual void accept(WidgetVisitor* v);
protected:
std::string text_;
};
class ConcreteWidget1: public Widget
{
public:
ConcreteWidget1(const std::string& text);
virtual std::string text() const override;
};
class ConcreteWidget2: public Widget
{
public:
ConcreteWidget2(const std::string& text);
virtual std::string text() const override;
};
.cpp file
void WidgetVisitor::visit(ConcreteWidget1& w1) {
cout << w1.text() << '\n';
}
void WidgetVisitor::visit(ConcreteWidget2& w2) {
cout << w2.text() << '\n';
}
void WidgetVisitor::visit(Widget& w) {
cout << w.text() << '\n';
}
Widget::Widget(const std::string& text): text_(text) { }
string Widget::text() const {
return "Widget" + text_;
}
void Widget::accept(WidgetVisitor* v) {
v->visit(*this);
cout << "in the class " << text_ << '\n';
}
ConcreteWidget1::ConcreteWidget1(const string& text): Widget(text) { }
string ConcreteWidget1::text() const {
return "ConcreteWidget1" + text_;
}
ConcreteWidget2::ConcreteWidget2(const string& text): Widget(text) { }
string ConcreteWidget2::text() const {
return "ConcreteWidget2" + text_;
}
main.cpp
int main() {
WidgetVisitor* visitor = new WidgetVisitor();
std::vector<Widget*> v;
v.push_back(new Widget(" 1"));
v.push_back(new ConcreteWidget1(" 2"));
v.push_back(new ConcreteWidget2(" 3"));
v.push_back(new ConcreteWidget1(" 4"));
for (auto & w: v)
w->accept(visitor);
return 0;
}
Output is:
Widget 1 in the class 1 ConcreteWidget1 2 in the class 2 ConcreteWidget2 3 in the class 3 ConcreteWidget1 4 in the class 4