? ? 這篇文章是本人在學(xué)習(xí)C++primer第15章Query程序時對自己所遇到困惑的總結(jié),我發(fā)現(xiàn)其實這節(jié)最難理解的正如書中所說是理解這個程序的設(shè)計思路。因此本文也主要是記錄本人如何理解這個程序的設(shè)計思路的贴唇。
????要理解這一章的文本查詢程序應(yīng)回顧下12.3.2中的TextQuery類,該類還是比較容易理解,就不在此贅述瞪讼。15.9.1節(jié)首先講了為什么不直接繼承12.3.2節(jié)的TextQuery類,來實現(xiàn)不同類型的查詢粹断。書中舉的例子就是如果用這種方法的話符欠,要實現(xiàn)邏輯非查詢,就必須要知道除了待查詢的單詞之外的所有單詞瓶埋,然而這一般是不可能的希柿。所以才設(shè)計出一套獨立的繼承體系:
其中每個類都將包含eval和rep兩種方法。其中eval函數(shù)接收一個TextQuery用于保存文本和所有單詞及其出現(xiàn)的行的集合养筒,返回一個包含特定單詞及其出現(xiàn)行的QueryResult類曾撤。為什么要有這個函數(shù)也是比較好理解的,因為無非輸入是所有內(nèi)容晕粪,而輸出是一種經(jīng)過處理的特殊內(nèi)容挤悉。
? ? 下面開始設(shè)計這個程序。首先要明確需求巫湘,即最終代碼應(yīng)該要能實現(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è)計好的程序中拷貝過來的測試主程序装悲,看到這種查詢方式,對我們理解這一節(jié)有非常大的幫助(書中只給了第三句尚氛,非常不方便我們理解這套程序)诀诊。如果我們把這個作為一個需求,就不難理解書中為什么要隱藏之前想要設(shè)計的那一套繼承體系的類阅嘶。因為我們并不想用戶去使用各種不同的類來實現(xiàn)不同形式的查詢畏梆,如果只用一個Query類來實現(xiàn)不是最好的嗎?
? ? Query q的目的是構(gòu)造一張圖:
而q.eval(tQuery)就是沿著這張圖進(jìn)行求值(顯示)的過程奈懒。這樣我們就很容易理解為什么要給Query設(shè)計eval和rep操作奠涌。q = Query("fiery")的含義是q綁定到一個存放著string的新WordQuery對象上。對于重載運算符應(yīng)該需要完成的任務(wù)磷杏,例如AndQuery就應(yīng)該是保存兩個Query對象溜畅,其他類似。
? ? 如果理解了以上內(nèi)容再去看書中的內(nèi)容的話极祸,就容易很多了慈格。
?待更:如何構(gòu)建這張圖怠晴,以及如何沿著這張圖求值。