shared_ptr实现类的数据共享(文本查询类的定义
面对过程
vector<>
来存输入文件的每一行map<string,set<int>>
,每一个单词映射一个集合,集合包含其出现的行数istringstream
:将每一行string
放到字符串流里面,通过流来分割出单词,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
671 #include <iostream>
2 #include <sstream>
3 #include <fstream>
4 #include <vector>
5 #include <set>
6 #include <map>
7 #include <string>
8
9 #include <cstdlib>
10 using namespace std;
11 using line_no = vector<string>::size_type;
12 vector<string> file;
13 map<string,set<line_no>> wm;
14
15 string cleanup_str(const string& word) {
16 string ret;
17 for (auto it = word.begin(); it!=word.end(); it++) {
18 if (!ispunct(*it))
19 ret += tolower(*it);
20 }
21 return ret;
22 }
23
24 ostream& query_and_print(const string& sought,ostream& os) {
25 auto loc = wm.find(sought);
26 if (loc == wm.end()) {
27 os << sought << " have seen zero times " << endl;
28 } else {
29 // loc is a iterator , and pair<> is being pointed
30 auto lines = loc->second;
31 os << sought << "have seen " << lines.size() << " times " << endl;
32 for (auto num : lines)
33 os << "\t (The " << num+1 << " line) " << *(file.begin() + num) << e#
34 }
35 return os;
36 }
37
38 void input_txt(ifstream& is) {
39 string text;
40 while (getline(is,text)) {
41 file.push_back(text);
42 int n = file.size() - 1;
43 istringstream line(text);
44 string word;
45 while (line >> word)
46 wm[cleanup_str(word)].insert(n);
47 }
48 }
49 void runQueries(ifstream& infile) {
50 input_txt(infile);
51 while (true) {
52 cout << "Enter word to look for, or q to quit: ";
53 string s;
54 if (!(cin >> s) || s == "q") break;
55 query_and_print(s,cout);
56 }
57 }
58 int main() {
59 ifstream infile("1.in");
60 if (!infile) {
61 cout << " fail to open infile ";
62 return -1;
63 }
64 runQueries(infile);
65 infile.close();
66 return 0;
67 }
关于&是否会增加shared_ptr<>的引用计数问题
- 变量的引用只是变量的别名,并不会增加智能指针的引用计数
1
2
3
4
5
6
7
8
9
10
11
12
131 #include <iostream>
2 #include <memory>
3 using namespace std;
4
5 int main() {
6 shared_ptr<int> p (new int(24));
7 cout << p.use_count() << endl;
8
9 auto& q = p;
10 cout << " q.use_count()= " << q.use_count() << " *q= " << *q << endl;
11 cout << " p.use_coutn()= " << p.use_count() << " *p= " << *p << endl;
12 return 0;
13 } - 创建了一个新的
shared_ptr<>
对象并且指向同一块内存,自然就会增加shared_ptr
的引用计数1
2
3
4
5
6
7
8
9
10
11
12
131 #include <iostream>
2 #include <memory>
3 using namespace std;
4
5 int main() {
6 shared_ptr<int> p (new int(24));
7 cout << p.use_count() << endl;
8
9 auto q = p;
10 cout << " q.use_count()= " << q.use_count() << " *q= " << *q << endl;
11 cout << " p.use_coutn()= " << p.use_count() << " *p= " << *p << endl;
12 return 0;
13 }面对对象
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// 注意使用指针和对象之间的区别
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <memory>
using namespace std;
//QueryResult 保存查询结果的类,要想共享类之间的数据且不通过拷贝,shared_ptr<>来解决
class QueryResult;
class TextQuery {
public:
using line_no = vector<string>::size_type; //类型成员
TextQuery(ifstream&); //接收 文件流来读取文本
QueryResult query(const string&) const; //
private:
shared_ptr<vector<string>> file;
map<string, shared_ptr<set<line_no>>> wm; //string 关联一个 动态分配的set<>集合
};
TextQuery::TextQuery(ifstream& in):file(new vector<string>){
string text;
while (getline(in,text)) {
(*file).push_back(text);
int n = (*file).size() - 1;
istringstream line(text);
string word;
while (line >> word) {
// wm[word] 是一个shared_ptr<set<line_no>>指针,但是我们不确定他是否分配了内存
auto& lines = wm[word]; //& 不增加 引用计数
if (!lines) //如果 智能指针为空,.reset(新动态内存对象)
lines.reset(new set<line_no>);
(*lines).insert(n);
}
}
}
class QueryResult {
friend ostream& print(ostream&,const QueryResult&); //友元
public:
using line_no = vector<string>::size_type;
QueryResult(string s, shared_ptr<set<line_no>> p, shared_ptr<vector<string>> f) :sought(s), lines(p), file(f) {}
private:
// 查询结果3内容
string sought;
shared_ptr<set<line_no>> lines;
shared_ptr<vector<string>> file;
};
QueryResult TextQuery::query(const string& sought) const{
//如果 没有找到该单词所属的行,返回一个指向空set的shared_ptr,static(全局静态)保证了函数结束前内存不会被释放
static shared_ptr<set<line_no>> nodata(new set<line_no>);
auto loc = wm.find(sought);
if (loc == wm.end())
//将TextQuery的内存也让QueryResult的shared_ptr指向,这样就能共享内存,
return QueryResult(sought, nodata, file);
else
return QueryResult(sought,loc->second,file);
}
ostream& print(ostream& os, const QueryResult& qr) { //接收一个查询结果类
os << qr.sought << " occurs " << qr.lines->size() << " times " << endl;
for (auto num : *qr.lines)
os << "\t(line " << num + 1 << ") " << *(qr.file->begin() + num) << endl;
return os;
}
int main() {
ifstream in("a.txt");
if (!in) { //文件打开失败,return
cout << "fail to open file " << endl;
return -1;
}
TextQuery solution(in); //传入输入流对象初始化
while (1) {
cout << " Enter word to look for, or q to quit: ";
string s;
if (!(cin >> s) || s == "q") break;
print(cout,solution.query(s)); //querys返回一个QueryResult对象
}
return 0;
}
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!