C++Primer 16章·11-20

16.11 List的定义是错误的,应该如何修正?

修改后:

1
2
3
4
5
6
7
8
9
10
11
12
template <typename elemType> class ListItem;
template <typename elemType> class List {
public:
List();//在List模板内调用List可以省略<>
List(const List<elemType> &);
List& operator=(const List<elemType>&);
~List();
//ListItem在模板类定义外调用需要加上<>
void insert(ListItem<elemType>* ptr, elemType value);
private:
ListItem * front, * end;
};

16.12 编写你自己版本的Blob和BlobPtr,包含书中未定义的多个const

这道题涉及到新学的模板类的定义模板友元的声明以及之前学到的const类型函数智能指针运算符重载等内容。如果跟我一样战线拉得比较长得同学可以试着重写以下这个Blob。如果之前学得比较好的话,可以直接从12章-19题Strbol.h改成template模板熟悉一下模板的声明。程序如下:

blob.h

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
#ifndef BLOB_H
#define BLOB_H

#include<vector>
#include<string>
#include<memory>
#include<initializer_list>
using namespace std;

template <typename t> class blobptr;
template <typename T> bool operator==(const blobptr<T>&, const blobptr<T>&);

template<typename T> class blob {
friend class blobptr<T>;
public:
blob();
blob(initializer_list<T> il);//接受{}列表初始化

string::size_type size() const { return data->size(); }
bool empty() const { return data->empty(); }
void push_back(const T& t) { data->push_back(t); }
void push_back(const T&& t) { data->push_back(t); }
void pop_back();
T& front();
const T& front()const;
T& back();
const T& back()const;
T& operator[](string::size_type i);
const T& operator[](string::size_type i) const;
//与书上不同,改为了const版本,
//同时blobptr构造函数的接受参数也要改为const版本的引用
blobptr<T> begin() const {return blobptr<T>(*this);}
blobptr<T> end() const {return blobptr<T>(*this,data->size());}
private:
shared_ptr<vector<T>> data;
void check(string::size_type i,const string& s)const;//检查溢出
};

template<typename T> blob<T>::blob() : data(make_shared<vector<T>>()){}
template<typename T> blob<T>::blob(initializer_list<T> il):
data(make_shared<vector<T>>(il)){}
template<typename T> void blob<T>::pop_back() {
check(0, "no elem here");
return data->pop_back();
}
template<typename T> T& blob<T>::back() {
check(0, "no elem here");
return data->back();
}
template<typename T> const T& blob<T>::back()const {
check(0, "no elem here");
return data->back();
}
template<typename T> T& blob<T>::front() {
check(0, "no elem here");
return data->front();
}
template<typename T> const T& blob<T>::front()const {
check(0, "no elem here");
return data->front();
}
template<typename T> T& blob<T>::operator[](string::size_type i) {
check(i, "out of range");
return (*data)[i];
}
template<typename T> const T& blob<T>::operator[](string::size_type i)const {
check(i, "out of range");
return (*data)[i];
}
template<typename T>
void blob<T>::check(string::size_type i, const string& s)const {
if (i >= data->size())
throw out_of_range(s);
}

//blobptr相当于一个blob的迭代器
template <typename t> class blobptr {
friend bool operator==<t>(const blobptr<t>& lhr, const blobptr<t>& rhr);
public:
blobptr():curr(0){}
blobptr( const blob<t> &pb ,const size_t sz = 0):wptr(pb.data),curr(sz){}
t & operator*() const;
blobptr & operator++();

private:
shared_ptr<vector<t>> check(const size_t sz,string msg) const;
weak_ptr<vector<t>> wptr;
size_t curr;
};
template <typename t>
shared_ptr<vector<t>> blobptr<t>::check(const size_t sz,string msg)const {
auto ret = wptr.lock();
if(!ret)
throw runtime_error("unbond");
else if(sz >= ret->size())
throw out_of_range(msg);
return ret;
}
template <typename t>
t & blobptr<t>::operator*()const{
auto pb = check(curr,"out of range");
return (*pb)[curr];
}
template <typename t>
blobptr<t> & blobptr<t>::operator++(){
check(curr,"the end");
++curr;
return *this;
}

template <typename T>
bool operator==(const blobptr<T>& lhr, const blobptr<T>& rhr) {
return (lhr.curr == rhr.curr );
}

#endif // !BLOB_H

main.cpp

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
#include<iostream>
#include<string>
#include"blob.h"

using namespace std;

int main(int argc, char** argv) {
//测试 blob 功能(int)
cout << "普通版本功能测试" << endl;
blob<int> a = {1,2,3,4,5,6,7,8};
cout << a.back() << endl;
cout << a[2] << endl;
//测试 blobptr 功能(string)
blob<string> b = { "abc","def","ghi","jkl" };
blobptr<string> ib2(b, 2);
cout << *ib2 << endl;
auto ib = b.begin();//合成版本拷贝
cout<< *ib <<endl;
cout<< *(++ib) <<endl;
//检测const版本
cout << "const版本功能测试" << endl;
const blob<int> ca = { 1,2,3,4,5,6,7,8 };
cout << ca.back() << endl;
cout << ca[2] << endl;
const blob<string> cb = { "abc","def","ghi","jkl" };
auto icb = cb.begin();
cout << *icb << endl;
}