C++ Primer(第5版) 练习 15.41
练习 15.41 重新实现你的类,这次使用指向Query_base的内置指针而非shared_ptr。请注意,做出上述改动后你的类将不能再使用合成的拷贝控制函数。
环境:Linux Ubuntu(云服务器)
工具:vim
代码块
#include<iostream>
#include<vector>
#include<memory>
using namespace std;
class Query_base{
friend class Query;
protected:
using line_no = TextQuery::line::no;
virtual ~Query_base() = default;
private:
virtual QueryResult eval(const TextQuery &)const = 0;
virtual std::string rep() const = 0;
};
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);
Query(const Query& query): q(query.q), uc(query.uc) { --*uc; }
Query& operator=(const Query& query);
~Query();
private:
Query(Query_base* query): q(query), uc(new int(1)) {}
Query_base* q;
int* uc;
};
inline Query::Query(const std::string &s): q(new WordQuery(s)), uc(new int(1)) {}
inline Query::~Query(){
if(--*uc == 0){
delete q;
delete uc;
}
}
inline Query& Query::operator=(const Query& query){
++*query.uc;
if(--*uc == 0){
delete q;
delete uc;
}
q = query.q;
uc = query.uc;
return *this;
}
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 new NotQuery(operand);
}
class BinaryQuery: public Query_base{
protected:
BinaryQuery(const Query &l, const Query &r, std::string s): lhs(l), rhs(r), opSym(s) {}
std::string rep() const { return "(" + lhs.rep() + " " + opSym + " " + rhs.rep() + ")"; }
Query lhs, rhs;
std::string opSym;
};
class AndQuery: public BinaryQuery{
friend Query operator&(const Query &, const Query &);
AndQuery(const Query &left, const Query &right): BinaryQuery(left, right, "&") {}
QueryResult eval(const TextQuery&) const;
};
inline Query operator&(const Query &lhs, const Query &rhs){
return new AndQuery(lhs, rhs);
}
class OrQuery: public BinaryQuery{
friend Query operator|(const Query &, const Query &);
OrQuery(const Query &left, const Query &right): BinaryQuery(left, right, "|") {}
QueryResult eval(const TextQuery&) const;
};
inline Query operator|(const Query &lhs, const Query &rhs){
return new OrQuery(lhs, rhs);
}