将不同的查询建模成相互独立的类,共享一个公共基类,包含两个操作:接受一个文本并返回结果;用来转换初识文本和其他形式的操作

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());
}