将不同的查询建模成相互独立的类,共享一个公共基类,包含两个操作:接受一个文本并返回结果;用来转换初识文本和其他形式的操作
Query_base类
class Query_base { friend class Query; protected: using line_no = TextQuery::line_no;//用于eval函数 virtual ~Query_base() = default;//虚析构函数 private: virtual QueryResult eval(const TextQuery&) const = 0; virtual std::string rep() const = 0; };
Query类
class Query { friend Query operator~(const Query &); friend Query operator|(const Query&, const Query&); friend Query operator&(const Query&, const Query&); public: Query(const std::string&);//构建新的WordQuery对象 //调用对应的接口 QueryResult eval(const TextQuery &t) const {return q->eval(t);} std::string rep() const {return q->rep();} private: Query(std::shared_ptr<Query_base> query) : q(query){} std::shared_ptr<Query_base> q; };
Query的输出运算符
std::ostream& operator<<(std::ostream &os, const Query &query) { return os<< query.rep(); }
派生类
class WordQuery: public Query_base { friend class Query; WordQuery(const std::string &s): query_word(s); QueryResult eval(const TextQuery &t) const {return t.query(query_word);} std::string rep() const {return query_word;} std::string query_word; }; inline Query::Query(const std::string &s): q(new WordQuery(s)){} class NotQuery: public Query_base { friend Query operator~(const Query&); NotQuery(const Query &q): query(q){} std::string rep() const {return "~("+query.rep()+")";} QueryResult eval(const TextQuery&) const; Query query; }; inline Query operator~(const Query &operand) { return std::shared_ptr<Query_base> (new NotQuery(operand)); }
eval函数
QueryResult OrQuery::eval(const TextQuery& text) const { auto right = rhs.eval(text), left = lhs.eval(text); auto ret_lines = make_shared_<set<line_no>>(left.begin(), left.end()); ret_lines->insert(right.begin(), right.end()); return QueryResult(rep(), ret_lines, left.get_file()); }