将不同的查询建模成相互独立的类,共享一个公共基类,包含两个操作:接受一个文本并返回结果;用来转换初识文本和其他形式的操作
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());
}
京公网安备 11010502036488号