C++Primer 574页 实现Query类和Query_base类

最终希望实现的功能:

int main()
{
	ifstream ifs("storyDataFile.txt");
	TextQuery tq(ifs);
	Query q = Query("fiery") & Query("bird") | Query("wind");
	cout << q << endl;
	print(cout,q.eval(tq));
	return 0;
}
  • TextQuery类变量tq将文件中的内容存储起来,有每一个单词的行号信息。
  • Query("bird")建立一个Query对象,"bird"是要找的词。注意这个对象本身不存TextQuery类变量,只存要找的string。
  • q也是一个Query对象,但是它要找的是fiery和bird同时出现,或者wind出现的行。
  • cout<<q打印一条信息,显示要查询的目标,比如((fiery & bird) | wind)
  • q.eval(tq)调用Query类的eval成员函数,在这里才将TextQuery类变量tq传入,获得针对某个文件的查询结果。

面向对象的解决方案

1.派生关系

Query是接口类。最简单的Query("bird")是Query类,Query("fiery") & Query("bird")也是Query类,这些Query都可以使用eval函数获得查找信息。很明显,虽然都是Query类,但是eval函数要做的处理明显是不同的,所以Query应该存一个指针,用这个指针动态调用不同派生类的eval函数。

一个最简单的派生类当然是auto q = Query("bird")中使用的,起名为WordQuery,它存储要查找的单词,它的eval函数接受一个TextQuery对象,获得bird的查询信息。所以Query接受string参数的构造函数,将自己的指针绑定到一个WordQuery类对象上。

Query::Query(const std::string &s)
{
	q =std::shared_ptr<Query_base> (new WordQuery(s));
}

Query("fiery") & Query("bird")也是一个Query,符号重载函数operator&接受两个Query对象,返回一个新的Query对象,这个新的Query的构造函数是

Query(std::shared_ptr<Query_base> query) : q(query) {}

这里的std::shared_ptr<Query_base> query当然应该绑定一个新的继承类,名为AndQuery。AndQuery有两个Query类型的成员left和right,它的构造函数接受两个Query成员来初始化left和right。AndQuery的eval函数利用这两个Query成员的eval函数,把它们的查找信息里的行号做一个并集,再创建一个新的查找信息类返回。
也就是说,AndQuery存储的是两个Query类成员,调用AndQuery的eval函数时,它就会调用成员的eval函数,再进行并集处理返回。

同理,OrQuery和NotQuery分别在|和~运算符重载中使用。

由于OrQuery和AndQuery都存储两个Query对象,所以在它们之上再加一个抽象类BinaryQuery。BinaryQuery、NotQuery和WordQuery都继承自Query_base类。

2.rep和eval的调用过程。

rep也是Query类和这些派生类的成员函数,功能就是返回一个用于打印的string字符串。
Query q = Query("fiery") & Query("bird") | Query("wind");调用q.rep()函数时,调用顺序是:

  1. 调用OrQuery的rep函数。(因为右边最后执行的是|运算,所以q存的是一个OrQuery指针)
  2. 上一步又需要分别调用left的rep函数和right的rep函数。left的rep函数需要调用AndQuery的rep函数,right需要调用WordQuery的rep函数。
  3. AndQuery的rep函数又需要分别调用left和right的rep函数,这两个成员都调用的是WordQuery的rep函数。
  4. WordQuery的rep函数是最底层了,不再继续向下调用。

eval函数的调用过程类似。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值