C++11访问者模式展示
2021-07-18 本文已影响0人
FredricZhu
题目
image.png
题目作者把accept和visit方法写反了,但是这不影响做题。
你也反着写就行了。
就是看着有点别扭。
这里的实现方式是传统的双向转发方式。
就是每个被访问对象有一个accept方法,接收访问者的访问。
访问对象有一堆visit方法,可以访问各种对象。[我是按正常的思路来说的,和代码刚好相反。]
这是这23种中最复杂的一个模式了。
因为它涉及到类层级的遍历。
程序代码如下,
#include <string>
#include <sstream>
using namespace std;
struct Value;
struct AdditionExpression;
struct MultiplicationExpression;
struct ExpressionVisitor
{
virtual void accept(Value& e) = 0;
virtual void accept(AdditionExpression& ae) = 0;
virtual void accept(MultiplicationExpression& me) = 0;
};
struct Expression
{
virtual void visit(ExpressionVisitor& ev) = 0;
};
struct Value : Expression
{
int value;
Value(int value) : value(value) {}
void visit(ExpressionVisitor& ev) {
ev.accept(*this);
}
};
struct AdditionExpression : Expression
{
Expression &lhs, &rhs;
AdditionExpression(Expression &lhs, Expression &rhs) : lhs(lhs), rhs(rhs) {}
void visit(ExpressionVisitor& ev) {
ev.accept(*this);
}
};
struct MultiplicationExpression : Expression
{
Expression &lhs, &rhs;
MultiplicationExpression(Expression &lhs, Expression &rhs)
: lhs(lhs), rhs(rhs) {}
void visit(ExpressionVisitor& ev) {
ev.accept(*this);
}
};
struct ExpressionPrinter : ExpressionVisitor
{
void accept(Value& e) override {
oss << e.value;
}
// 所有加法都需要()
void accept(AdditionExpression& ae) override {
oss << "(";
ae.lhs.visit(*this);
oss << "+";
ae.rhs.visit(*this);
oss << ")";
}
// 乘法只有右值是加法的时候需要()
void accept(MultiplicationExpression& me) override {
bool need_braces = (typeid(me.rhs) == typeid(AdditionExpression));
if(need_braces) oss << "(";
me.lhs.visit(*this);
oss << "*";
me.rhs.visit(*this);
if(need_braces) oss << ")";
}
string str() const {
return oss.str();
}
private:
ostringstream oss;
};