参考理解了下,实现上有不同。
http://blog.youkuaiyun.com/zhaoxy_thu/article/details/3799516
自己实现的代码地址:
https://github.com/anribras/QueryOop
TextQuery
最开始仅是查询某个单词所在的行数。
文本存储到内存,选择vector
map数据结构保存查询结果 map
OOP实现
真正的面向对象,类关系:
Query_base
WordQuery
NotQuery
BinaryQueryAndQuery
OrQuery
WordQuery解决单个查询
Query
Query隐藏继承细节,核心成员是一个指向基类的base指针.
核心思想就是封装基类指针!,然后灵活的调用下面的函数.
QueryResult eval(TextQuery & t);
问题最后抽象成为一个布尔查询表达式:
Query q = ~(Query("good") | (Query("boy") & Query("girl")));
QueryResult r= q.eval(TextQuery("xxx.file");
本质上就是虚函数里再调用虚函数,形成层次, 最外层的优先级最低(~),括号扩起来的优先级别最高(&).
q.eval –>NotQuery::eval NotQuery里的基类指针,指向了一个OrQuery
OrQuery::eval, 含有两个指针,一个指向WordQuery,一个指向AndQuery,
因此分别调用了WordQuery::eval和AndQuery::evalWordQuery::eval 检查单词“good”
AndQuery::eval 又含2个指针(Query对象),指向2个WordQueryWordQuery::eval 检查单词“boy”
WordQuery::eval 检查单词“girl”继续做AndQuery::eval的And动作
继续做OrQuery::eval的Or动作
继续做NotQuery::eval未完成的Not动作
例如 Query | Query: 操作返回一个Query, 用派生类的指针构造。
friendly Query operator|(const Query a, const Query b)
{
return new OrQuery(a,b);
}
//这里是隐式转换,调用下面的转换构造函数
Query(Query * ptr) : base(ptr) {}
OrQuery派生自BinaryQuery,因此派生类的构造又是调用了基类的构造函数
OrQuery(Query a, Query b) : BinaryQuery(a,b,"|") {}
Binary将a,b,保存到自己的成员变量Query left和Query right中。
智能指针的引入
在创建表达式的query时,相当于Query* base = new OrQuery(…);需要手动释放,用智能指针解决手动释放的问题。
另外定义一个类为share_ptr和直接定义一个对象 使用上其实并没有区别,
shared_ptr<Class> ptrc;
Class * c;
Class c;
区别在:
1 内存维护上,ptrc可以自动管理内存释放,指针分配的内存需要delete,普通对象跟随生命周期自动析构
2 资源上,对象赋值时发生拷贝,shared_ptr和指针共享;
3 生命周期share_ptr取决引用值,指针delete,而且必须在定义他的类对象结束之前,
普通对象跟随定义他的类的生命周期