从对象角度进行的思考。2014-01-21
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307 |
#include <iostream> #include <fstream> #include <sstream> #include <string> #include <vector> #include <map> #include <set> #include <memory> #include <algorithm> using
namespace
std; class
QueryResult { public : friend
ostream &print(ostream &, const
QueryResult &); QueryResult(string s, shared_ptr<set< int >> w, shared_ptr<vector<string>> f) :word(s), wordlineSet(w), file(f) { //cout<< "QueryResult construst"<<endl; //cout << *file->begin()<<endl; } set< int >::iterator begin() { return
wordlineSet->begin(); } set< int >::iterator end() { return
wordlineSet->end(); } std::shared_ptr<std::vector<std::string>> get_file() { return
file; } private : string word; shared_ptr<set< int >> wordlineSet; shared_ptr<vector<string>> file; }; class
TextQuery { public : TextQuery(ifstream &is) : file( new
vector<string>) { string text; while
(getline(is, text)) { //cout << "TextQuery construct"<<endl; file->push_back(text); //cout << text <<endl; //cout << file->size()<<endl; int
lineNumber = file->size() - 1; //存入vector的行数应该是实际行数减1 istringstream line(text); string word; while
(line >> word) { auto
&lines = wordmap[word]; if
(!lines) lines.reset( new
set< int >); lines->insert(lineNumber); /* 关于. 和 -> 操作: .是对lines本身操作 ->是对lines(智能指针)所指向的对象操作 */ } } } QueryResult query( const
string &s) const { static
shared_ptr<set< int >> nodata( new
set< int >); auto
wordloc = wordmap.find(s); if
(wordloc == wordmap.end()) return
QueryResult(s, nodata, file); else return
QueryResult(s, wordloc->second, file); } private : shared_ptr<vector<string>> file; map<string, shared_ptr<set< int >>> wordmap; }; class
Query_base { friend
class
Query; protected : virtual
~Query_base() = default ; private : virtual
QueryResult eval( const
TextQuery&) const
= 0 { cout << "Query_base::eval()"
<< endl; } virtual
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
string&); //构造函数 QueryResult eval( const
TextQuery &t) const { return
q->eval(t); } string rep() const { return
q->rep(); } private : Query(shared_ptr<Query_base> query) : q(query) { cout << "Query(shared_ptr<Query_base> query) "
<< endl; } shared_ptr<Query_base> q; }; //重载输出(<<)操作符 std::ostream & operator<<(std::ostream &os, const
Query &query) { return
os << query.rep(); } //单词查询类 class
WordQuery : public
Query_base { friend
class
Query; WordQuery( const
string &s) : query_word(s) {} QueryResult eval( const
TextQuery &t) const { cout << "WordQuery eval() " << endl; return
t.query(query_word); } string rep() const { cout << "***WordQuery rep()" << endl; return
query_word; }; string query_word; }; //Query接口实现动态绑定WordQuery inline
Query::Query( const
std::string &s) : q( new
WordQuery(s)) { cout << "Query::Query(const std::string &s) "
<<s<< endl; } //取反查询 class
NotQuery : public
Query_base { friend
Query operator~ ( const
Query &); //友元是取反函数 NotQuery( const
Query &q) : query(q) { cout << "NotQuery construct"
<< endl; } string rep() const
{ return
"~("
+ query.rep() + ")" ; } QueryResult eval( const
TextQuery &t) const ; Query query; }; //实现取反操作, 动态绑定NotQuery对象 //最终使用的是WordQuery类, Query构建需要WordQuery, 再传入NotQuery; inline
Query operator~ ( const
Query &operand) { cout << "Query operator~ "
<< endl; return
shared_ptr<Query_base>( new
NotQuery(operand)); } //二元查询, 没有eval, 则继承纯虚函数 class
BinaryQuery : public
Query_base { protected : BinaryQuery( const
Query &l, const
Query &r, std::string s) : lhs(l), rhs(r), opSym(s) { cout << "BinaryQuery"
<< endl; } 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, "&" ) { cout << "AndQuery"
<< endl; } QueryResult eval( const
TextQuery&) const ; }; inline
Query operator& ( const
Query& lhs, const
Query& rhs) { cout << "Query operator& "
<< endl; return
shared_ptr<Query_base>( 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, "|" ) { cout << "OrQuery"
<< endl; } QueryResult eval( const
TextQuery&) const ; }; inline
Query operator| ( const
Query& lhs, const
Query& rhs) { cout << "Query operator| "
<< endl; return
shared_ptr<Query_base>( new
OrQuery(lhs, rhs)); } QueryResult OrQuery::eval( const
TextQuery& text) const { auto
right = rhs.eval(text), left = lhs.eval(text); auto
ret_lines = std::make_shared<std::set< int > >(left.begin(), left.end()); ret_lines->insert(right.begin(), right.end()); return
QueryResult(rep(), ret_lines, left.get_file()); } QueryResult AndQuery::eval( const
TextQuery& text) const
{ auto
left = lhs.eval(text), right = rhs.eval(text); //调用的是WordQuery的eval auto
ret_lines = std::make_shared<std::set< int >>(); set_intersection(left.begin(), left.end(), right.begin(), right.end(), inserter(*ret_lines, ret_lines->begin())); return
QueryResult(rep(), ret_lines, left.get_file()); } QueryResult NotQuery::eval( const
TextQuery& text) const { cout << " QueryResult NotQuery::eval(const TextQuery& text) const" << endl; auto
result = query.eval(text); //调用WordQuery.eval; auto
ret_lines = std::make_shared<std::set< int >>(); auto
beg = result.begin(), end = result.end(); auto
sz = result.get_file()->size(); for
( size_t
n = 0; n != sz; ++n) { if
(beg == end || *beg != n) { cout << n << endl; //cout << *beg << endl; ret_lines->insert(n); } else
if
(beg != end) ++beg; } return
QueryResult(rep(), ret_lines, result.get_file()); } bool
get_word(std::string& str) { std::cout << "enter word to look for, or q to quit: "
<< std::endl; if
(!(std::cin >> str) || str == "q" ){ std::cout << str; return
false ; } else { std::cout << str; return
true ; } } string make_plural( const
int
length, const
string s1, const
string s2) { if
(length == 0) return
s1; if
(length == 1) return
s1; else return
s2; } ostream &print(ostream & os, const
QueryResult &qr) { //cout << *(qr.file->begin())<<endl; //cout<< "print function running"<<endl; os << qr.word << " occurs "
<< qr.wordlineSet->size() << " "
<< make_plural(qr.wordlineSet->size(), "time" , "times" ) << endl; for
( auto
num : *qr.wordlineSet) os << " (line "
<< num + 1 << ")"
<< *(qr.file->begin() + num) << endl; return
os; } void
runQueries(ifstream &infile) { TextQuery t1(infile); while
( true ) { cout << "Enter word to look for,or q to quit"
<< endl; string s; if
(!(cin >> s) || s == "q" ) break ; print(cout, t1.query(s)) << endl; } } void
main() { ifstream in; //runQueries(in); TextQuery file = in; Query q1( "the" ); Query q(q1); //Query q = Query("the"); //Query q = ~Query("was"); //Query q = Query("were") | Query("was"); //Query q = Query("was") & Query("the"); //Query q = Query("was") & Query("the") | Query("were"); cout << "-=--=--=-=-=-=-=---==-=-==-=-=-=-="
<< endl; const
auto
results = q.eval(file); cout << "Executing Query for: "
<< q << endl; print(cout, results) << endl; } |
------------------------------------------------------------
从main()函数说起
1234567891011121314151617181920void
main()
{
ifstream in;
//runQueries(in);
TextQuery file = in;
Query q1(
"the"
);
Query q(q1);
//Query q = Query("the");
//Query q = ~Query("was");
//Query q = Query("were") | Query("was");
//Query q = Query("was") & Query("the");
//Query q = Query("was") & Query("the") | Query("were");
cout <<
"-=--=--=-=-=-=-=---==-=-==-=-=-=-="
<< endl;
const
auto
results = q.eval(file);
cout <<
"Executing Query for: "
<< q << endl;
print(cout, results) << endl;
}
Query q1("the");
Query q(q1);
这两句,分别展示了Query类的两种构造函数。
第一种是,接受一个字符串,给类成员对象 q 赋值为 new WordQuery(s) ,q 的类型是shared_ptr<Query_base>,也就是说,q 的值是地址。
Query(const std::string &s) : q(new WordQuery(s))
{
cout << "Query::Query(const std::string &s) " <<s<< endl;
}第二种是,接受一个shared_ptr<Query_base>的变量(其实是个地址),然后把该地址赋给成员变量 q,main()函数中,Query q(q1) ,q1的成员变量是 new WordQuery(s)的地址。
Query(shared_ptr<Query_base> query) : q(query)
{
cout << "Query(shared_ptr<Query_base> query) " << endl;
}
总结起来,赋值到底赋的是什么?是类型中的成员变量!! (暂不涉及类型转换)
下面看最复杂的。
Query q = Query("was") & Query("the") | Query("were");
执行顺序先确定下,((was & the) | were)。
首先,等号右边,有三个带字符的Query类型,所以,有调用三次Query(const std::string &s) ,各自对象内的成员变量q都有各自的地址。
接下来,执行内层括号的 & 运算符,形参列表是,分别在&号左右两侧对象的引用,实际上传的是两个地址,因为Query类型的对象只有一个成员变量,并且是地址值。
Query operator& (const Query& lhs, const Query& rhs)
{
cout << "Query operator& " << endl;
return shared_ptr<Query_base>(new AndQuery(lhs, rhs));
}
因此(was & the) 就等于 shared_ptr<Query_base>(new AndQuery(lhs, rhs)),说白了就是个地址。我暂时把这个地址 定义为 addr。(这么定义,其实是因为编译器确实创建了一个Query temp = (was & the)的地址,只是这是一个临时变量)
接着addr | Query("were"),| 运算符,形参列表同样接受两个对象(其实是地址)。
Query operator| (const Query& lhs, const Query& rhs)
{
cout << "Query operator| " << endl;
return shared_ptr<Query_base>(new OrQuery(lhs, rhs));
}
最后返回的是 shared_ptr<Query_base>(new OrQuery(lhs, rhs)),一个地址。C++很有意思的地方就在这里,地址指向对象,对象里存的还是地址。。
程序运行结果:
Query::Query(const std::string &s) were
Query::Query(const std::string &s) the
Query::Query(const std::string &s) was
Query operator&
BinaryQuery
AndQuery
Query(shared_ptr<Query_base> query)
Query operator|
BinaryQuery
OrQuery
Query(shared_ptr<Query_base> query)
从运行结果中,可以看出来,每一个类的构造函数运行的情况。
上面执行的只是 Query q = Query("was") & Query("the") | Query("were"); 这么一句。
C++PRIMER-5TH 15.9 文本查询程序再探 练习理解(二)
原文:http://www.cnblogs.com/wk23/p/3529057.html