0%

笔记

文本查询程序

用智能指针实现类间数据传递

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
#include<iostream>
#include<memory>
#include<set>
#include<map>
#include<string>
#include<vector>
#include<fstream>
#include<sstream>

using namespace std;
using line_no=vector<string>::size_type;

/*在类TextQuery内寻找,将搜索结果传入类QueryResult*/

class QueryResult;
//此函数控制输出单词单复数
inline string make_plural(size_t ctr,const string &word,
const string &endi);
ostream& print(ostream&,const QueryResult&);

//该类存储数据
class TextQuery
{
public:
TextQuery(ifstream&);
QueryResult query(const string&) const;
private:
shared_ptr<vector<string>> file;
map<string,shared_ptr<set<line_no>>> wm;
};

//存储结果的类
class QueryResult
{
friend ostream& print(ostream&,const QueryResult&);
public:
QueryResult(string s,shared_ptr<set<line_no>> p,
shared_ptr<vector<string>> f);
private:
string search;
shared_ptr<set<line_no>> lines;
shared_ptr<vector<string>> file;
};

QueryResult::QueryResult(string s,shared_ptr<set<line_no>> p,
shared_ptr<vector<string>> f) : search(s), lines(p), file(f)
{}

TextQuery::TextQuery(ifstream &ifs) : file(new vector<string>)
{
string text;
while(getline(ifs,text))
{
file->push_back(text);
int n=file->size();
istringstream line(text);
string word;
while(line>>word)
{
auto &lines=wm[word];
if(!lines)
lines.reset(new set<line_no>);
lines->insert(n-1);
}
}
}

QueryResult TextQuery::query(const string &search) const
{
static shared_ptr<set<line_no>> nodata(new set<line_no>);
auto loc=wm.find(search);
if(loc==wm.end())
return QueryResult(search,nodata,file);
else
return QueryResult(search,loc->second,file);
}

inline string make_plural(size_t ctr,const string &word,
const string &endi)
{
return (ctr>1) ? word+endi : word;
}

ostream& print(ostream &cout,const QueryResult &qr)
{
cout<<qr.search<<" occurs "<<qr.lines->size()
<<" "<<make_plural(qr.lines->size(),"time","s")
<<endl;
for(auto num: *(qr.lines))
cout<<"\t(line "<<num+1<<") "<<
*(qr.file->begin()+num)<<endl;
return cout;
}

void runQueries(ifstream &ifs)
{
TextQuery tq(ifs);
while(true)
{
printf("enter word to look for, or q to quit\n");
string tmp;
if(!(cin>>tmp)||tmp=="q") break;
print(cout,tq.query(tmp))<<endl;
}
}

int main()
{
ifstream ifs;
ifs.open("C:\\test\\tst.txt",ios::in);
runQueries(ifs);
return 0;
}

调用类型

不同类型可以具有相同的调用形式
1
2
3
4
5
6
7
8
9
10
11
//函数
int add(int x, int y){return x+y;}
//lambda
auto mod=[](int x, int y){return x%y;};
//函数对象类
class divide
{
public:
int operator()(int x, int y){return x/y;}
};
//共享调用形式int(int, int)
function类型
1
2
3
4
5
6
//用map创建函数表
map<string,(int*)(int, int)> functable; //可以存储add
functable.insert(pair<string,int(*)(int, int)>{"+",add});
/*但不能存储mod与divide,
可以使用标准库function解决*/
function<int(int, int)> //表示接受两个int,返回一个int的可调用对象
计算器
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
#include<iostream>
#include<string>
#include<map>
#include<functional>
using namespace std;

int add(int x,int y){return x+y;}
class divide
{
public:
int operator()(int x,int y)
{
if(y==0) {printf("NaN\n");exit(EXIT_SUCCESS);}
return x/y;
}
};
int main()
{
auto mod=[](int x,int y)
{
if(!y) {return x;}
return x%y;
};
map<string,function<int(int, int)>> functable=
{
{"+", add},
{"-", minus<int>()},
{"*", [](int x, int y){return x*y;}},
{"/", divide()},
{"%", mod}
};
printf("请输入\n格式: 操作数 运算符 操作数2\n");
int x,y;
string operate;
cin>>x>>operate>>y;
printf("%d",functable[operate](x, y));
return 0;
}

复制对象每一部分

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
void logCall (const string& funcname);
class Customer
{
public:
Customer(const Customer& rhs);
Customer& operator==(const Customer& rhs);
private:
string name;
};

Customer::Customer(const Customer& rhs) : name(rhs.name)
{
logCall("customer copy constructor");
}
Customer& Customer::operator==(const Customer& rhs)
{
logCall("CUstomer copy assignment operator");
name = rhs.name;
return *this;
}
----------------------------------------Customer-----------------------------------------

class pro : public Customer
{
public:
pro();
pro(const pro& rhs);
pro& operator==(const pro& rhs);
private:
int priority;
};

//pro类内函数
pro::pro(const pro& rhs) : priority(rhs.priority)
{
logCall("Pro copy constructor");
};
pro& pro::operator==(const pro& rhs)
{
logCall("Pro copy assignment operator");
priority = rhs.priority;
return *this;
}
/*这时,pro中priority被拷贝,但pro类中继承自Customer的部分未被拷贝。编写拷贝构造函数
必须注意到其base class的部分*/

//正确做法
pro::pro(const pro& rhs) : priority(rhs.priority)
{
logCall("Pro copy constructor");
};
pro& pro::operator==(const pro& rhs)
{
logCall("Pro copy assignment operator");
priority = rhs.priority;
Customer::operator==(rhs);
return *this;
}

/*还需注意,若为class添加成员,必须修改所有构造函数*/

编写new与内存不足处理例程

伪码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void* operator new(std::size_t size)
{
if(size == 0)
size = 1;//0 byte 视为 1byte
for(;;)
{
尝试分配 size bytes;
if(成功)
return 指针指向分配的内存;

//分配失败
//获取当前new-handling函数
std::new_handler globhandler = std::set_new_handler(0);
std::set_new_handler(globhandler);

if(0 == globhandler) throw std::bad_alloc();
//调用
(*globhandler)();
}
}

另外,式void (* set_malloc_handler(void (*f)())) ();

声明了一个名为set_malloc_handler的函数,它接受一个函数指针void (*f)(),这个函数指针指向参数列表空,返回空的函数,返回一个函数指针,指向参数列表空,返回空的函数。