StrBlob类的实现(shared_ptr与weak_ptr的混用)
my_StrBlob.h
实现了2个类
StrBlob StrBlobPtr
StrBlob
成员包含shared_ptr<>
,StrBlobPtr
这个伴随类有weak_ptr<>
和shared_ptr
共享一块内存,在2个类之间建立一些接口作为参数的
initializer_list<>
的用法,实参数量未知但是实参类型相同,用法和vector
类似,但initializer_list<>
的元素是常量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#ifndef MY_STRBLOB_H
#define MY_STRBLOB_H
#include <vector>
#include <string>
#include <memory>
#include <initializer_list>
using namespace std;
class StrBlobPtr;
class StrBlob {
friend class StrBlobPtr;
public:
typedef vector<string>::size_type size_type;
StrBlob() :data(make_shared<vector<string>>()) {}
StrBlob(initializer_list<string> i1) :data(make_shared<vector<string>>(i1)) {}
size_type size() const { return data->size(); }
bool empty() const { return data->empty(); }
int get_use_count() const { return data.use_count(); }
void push_back(const string& t) { data->push_back(t); }
void pop_back();
string& front();
const string& front() const;
string& back();
const string& back() const;
// 将自己作为StrBlobPtr的构造函数参数来构造StrBlobPtr对象
StrBlobPtr begin();
StrBlobPtr end();
// 接收 const StrBlob & 对象来构造StrBlobPtr对象
StrBlobPtr begin() const;
StrBlobPtr end() const;
private:
shared_ptr<vector<string>> data;
void check(size_type,const string&) const;
};
inline void StrBlob::check(size_type i, const string& msg) const {
if (i >= data->size())
throw out_of_range(msg);
}
inline string& StrBlob::front() {
check(0,"front");
return data->front();
}
inline const string& StrBlob::front() const {
check(0,"const front");
return data->front();
}
inline string& StrBlob::back() {
check(0,"back");
return data->back();
}
inline const string& StrBlob::back() const{
check(0,"const back");
return data->back();
}
inline void StrBlob::pop_back() {
check(0,"pop_back");
data->pop_back();
}
class StrBlobPtr {
friend bool eq(const StrBlobPtr&, const StrBlobPtr&);
public:
StrBlobPtr():curr(0) {}
StrBlobPtr(StrBlob& a, size_t sz = 0) :wptr(a.data), curr(sz) {}
//接收const StrBlob & 对象的构造函数
StrBlobPtr(const StrBlob& a, size_t sz = 0) :wptr(a.data), curr(sz) {}
string& deref() const; //返回下标出的值
StrBlobPtr& incr(); //curr后移
StrBlobPtr& decr(); //curr前移
private:
size_t curr; //下标
weak_ptr<vector<string>> wptr; //此类的精华,weak_ptr<> 弱shared_ptr指针
shared_ptr<vector<string>> check(size_t,const string&) const;
};
inline shared_ptr<vector<string>> StrBlobPtr::check(size_t i, const string& msg) const {
auto ret = wptr.lock();
if (!ret)
throw runtime_error("empty");
if (i >= ret->size())
throw out_of_range(msg);
return ret;
}
inline string& StrBlobPtr::deref() const {
auto p = check(curr,"dereference past end");
return (*p)[curr];
}
inline StrBlobPtr& StrBlobPtr::incr() {
check(curr,"incement past end of StrBlobPtr");
++curr;
return *this;
}
inline StrBlobPtr& StrBlobPtr::decr() {
curr--;
// 直接减,然后检查不是-1就行了
check(-1,"decrment past end of StrBlobPtr");
return *this;
}// 实现了StrBlobPtr,开始实现与StrBlob之间的接口
inline StrBlobPtr StrBlob::begin() {
return StrBlobPtr(*this);
//返回指向首元素的StrBlobPtr
}
// 接收 const 对象
inline StrBlobPtr StrBlob::begin() const {
return StrBlobPtr(*this);
}
//返回指向最后一个元素的
inline StrBlobPtr StrBlob::end() {
auto ret = StrBlobPtr(*this,data->size());
return ret;
}
inline StrBlobPtr StrBlob::end() const {
return StrBlobPtr(*this, data->size());
}
inline bool eq(const StrBlobPtr& lhs, const StrBlobPtr& rhs) {
auto l = lhs.wptr.lock(); // 智能指针本着是一个对象, .来访问自己的成员
auto r = rhs.wptr.lock();
if (l == r) // 都为空,或者指向的对象一样
//空 或者 指向相同的元素
return (!r || lhs.curr == rhs.curr);
else
return false;
}
inline bool neq(const StrBlobPtr& lhs, const StrBlobPtr& rhs) {
return !eq(lhs,rhs);
}
#endif通过
StrBlobPtr
类来打印每个string
元素1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#include <iostream>
#include <fstream>
#include "Sales_data.h"
using namespace std;
int main() {
fstream in("1.in");
if (!in) {
cout << "faile to open 1.in" << endl;
return -1;
}
StrBlob b;
string s;
while (getline(in, s))
b.push_back(s);
// StrBlob.begin() 生成了StrBlobPtr对象,通过StrBlobPtr来访问每个元素的内容
for (auto it = b.begin(); neq(it, b.end()); it.incr())
cout << it.deref() << endl;
return 0;
}
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!