I am trying to implement Oppen's algorithm in C++.
The basic routines in this algorithm (print and scan) dispatch on a token type. It seems natural to implement this dispatch using the visitor pattern. The problem is: the routines are nested and the arguments to print() are enqueued in a stack during scan(). In order to avoid any memory problems, I would like to use smart pointers for the task.
So my implementation looks like this:
class Text;
class Line;
class Open;
class Close;
class Visitor {
/* Define virtual visit functions for concrete doc nodes:
*/
public:
virtual void visit(const Text&) = 0;
virtual void visit(const Line&) = 0;
virtual void visit(const Open&) = 0;
virtual void visit(const Close&) = 0;
};
class DocToken
{
protected:
explicit DocToken() {}
friend class Visitor;
public:
virtual void accept(Visitor * visitor) const = 0;
};
class Text : public DocToken {
public:
Text(std::string s) : text(s) {}
void accept(Visitor *visitor) const {
visitor -> visit (*this);
}
std::string text;
};
class Open : public DocToken { /* .. */ }
/* .. */
class Scan : public Visitor {
stream_t stream;
/* ... */
public:
void visit(const Open& x) {
/* ... */
stream.push_back(/* .. */ new Open() /* .. */);
/* ... */
}
void visit(const Text& x) {
/* ... */
stream.push_back(/* .. */ new Text(x) /* .. */);
/* ... */
}
/* .. */
}
As you can see, the Open token does not carry any data and can be constructed in place easily. The Text token does carry data (a std::string) and has to be copied in order to be pushed into the stream. The stream needs to consist of pointers due to the common abstract base class of Open and Text.
Since on the outside, there is a smart pointer to that text token, I'd like to avoid the copying and simply use the existing smart pointer. However, the accept method does not have access to that smart pointer.
Is there a way to implement a visitor pattern directly on smart-pointers? If not, how can I reduce the cost of copying the text token?
Visitor
? (Also, I wouldn't worry too much about the copying until you have profiled to show it is a problem). – Vlissingenshared_ptr
? I.e., do you have a range of shared pointers (to the base class), and you pass the visitor to them all? – Hadria