? ? 這篇文章是本人在學(xué)習(xí)C++primer第15章Query程序時(shí)對(duì)自己所遇到困惑的總結(jié),我發(fā)現(xiàn)其實(shí)這節(jié)最難理解的正如書中所說是理解這個(gè)程序的設(shè)計(jì)思路。因此本文也主要是記錄本人如何理解這個(gè)程序的設(shè)計(jì)思路的。
????要理解這一章的文本查詢程序應(yīng)回顧下12.3.2中的TextQuery類,該類還是比較容易理解,就不在此贅述。15.9.1節(jié)首先講了為什么不直接繼承12.3.2節(jié)的TextQuery類,來實(shí)現(xiàn)不同類型的查詢。書中舉的例子就是如果用這種方法的話,要實(shí)現(xiàn)邏輯非查詢,就必須要知道除了待查詢的單詞之外的所有單詞,然而這一般是不可能的。所以才設(shè)計(jì)出一套獨(dú)立的繼承體系:

其中每個(gè)類都將包含eval和rep兩種方法。其中eval函數(shù)接收一個(gè)TextQuery用于保存文本和所有單詞及其出現(xiàn)的行的集合,返回一個(gè)包含特定單詞及其出現(xiàn)行的QueryResult類。為什么要有這個(gè)函數(shù)也是比較好理解的,因?yàn)闊o非輸入是所有內(nèi)容,而輸出是一種經(jīng)過處理的特殊內(nèi)容。
? ? 下面開始設(shè)計(jì)這個(gè)程序。首先要明確需求,即最終代碼應(yīng)該要能實(shí)現(xiàn)如下形式的查詢:查詢形式
std::ifstream file("test.txt");
TextQuery tQuery(file);
Query q = Query("fiery") & Query("bird") | Query("wind");?
std::cout << q.eval(tQuery);
這是我從Github上一份已經(jīng)設(shè)計(jì)好的程序中拷貝過來的測試主程序,看到這種查詢方式,對(duì)我們理解這一節(jié)有非常大的幫助(書中只給了第三句,非常不方便我們理解這套程序)。如果我們把這個(gè)作為一個(gè)需求,就不難理解書中為什么要隱藏之前想要設(shè)計(jì)的那一套繼承體系的類。因?yàn)槲覀儾⒉幌胗脩羧ナ褂酶鞣N不同的類來實(shí)現(xiàn)不同形式的查詢,如果只用一個(gè)Query類來實(shí)現(xiàn)不是最好的嗎?
? ? Query q的目的是構(gòu)造一張圖:

而q.eval(tQuery)就是沿著這張圖進(jìn)行求值(顯示)的過程。這樣我們就很容易理解為什么要給Query設(shè)計(jì)eval和rep操作。q = Query("fiery")的含義是q綁定到一個(gè)存放著string的新WordQuery對(duì)象上。對(duì)于重載運(yùn)算符應(yīng)該需要完成的任務(wù),例如AndQuery就應(yīng)該是保存兩個(gè)Query對(duì)象,其他類似。
? ? 如果理解了以上內(nèi)容再去看書中的內(nèi)容的話,就容易很多了。
?待更:如何構(gòu)建這張圖,以及如何沿著這張圖求值。