object pool

object pool

实现了一个最基础的对象池,实现方式为
1.创建一个对象
2.从对象池取出该对象
3.使用完后返回池中

借助智能指针,在释放对象的时候再将该对象重新存入内存池。会使用到自定义deleter

  • 自定义删除器
  • 智能指针

需要把智能指针的默认deleter修改为自定义deleter,用shared_ptr会很不方便,因为无法直接将shared_ptr的deleter修改为自定义删除器(这句话不理解,可能是修改方式有关系?),可以通过新建对象再拷贝的方法来实现但是效率较低。而unique_ptr提供了简便的方法可以实现修改deleter。

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
#include <iostream>
#include <memory>
#include <vector>
#include <functional>
#include <random>
#include <cstdlib>
#include <set>
#include <bit>
#pragma GCC optimize(2) //O2优化
using namespace std;

// objectPool
template<typename T>
class UserPool {
private:
std::vector<std::unique_ptr<T>> user_pool;
public:
//using DelType = std::function<void(T*)>;

std::function<void(T*)> deleter = [](T* p) {
delete p;
};

void add(std::unique_ptr<T> t) {
this->user_pool.emplace_back(std::move(t));
}

//std::unique_ptr<T, DelType> get()
std::unique_ptr<T, decltype(deleter)> get() {
if (user_pool.empty()) {
cout << "empty students!" << endl;
}
//bind a custom deleter for default unique_ptr
std::unique_ptr<T, decltype(deleter)> ptr(user_pool.back().release(), [this](T* t) {
user_pool.push_back(std::unique_ptr<T>(t));
});
user_pool.pop_back();
return std::move(ptr);
}

[[nodiscard]] bool is_empty() const {
return user_pool.empty();
}

[[nodiscard]] int pool_size() const {
return user_pool.size();
}

};


// student struct
struct Users {
vector<int> activities;
int index;

//用户编号和随机生成一些其所拥有的活动
Users(int index, int activity_num) { // student index 用户编号, activity count 活动数量
this->index = index;
static uniform_int_distribution<unsigned> u(0, 9);
static default_random_engine e;
// 当种子和随机数生成器在循环内定义的时候,随机数生成的值会相同。static解决该问题
for (int i = 0; i < activity_num; ++i) {
int temp = u(e);
this->activities.emplace_back(temp);
}
}

[[nodiscard]] int Get_Variety() const {
cout << "用户 " << this->index << "的活动的个数为: " << (int)this->activities.size() << endl << endl;
return (int)this->activities.size();
}

~Users() {
cout << "delete " << this->index << endl;
}

};


void Display(vector<Users*>& pool) { //展示所有用户活动
for (auto& a : pool) {
cout << a->index << " : ";
for (auto& b : a->activities) {
cout << b << " ";
}
cout << endl;
}
}


int main() {
UserPool<Users> pool;
int user_num=3;
int ac_num=5;
//cout << "输入用户数:";
//cin >> user_num;
//cout << "输入每个用户的活动数: ";
//cin >> ac_num;
for (int i = 0; i < user_num; ++i) {
cout << "create user: " << i << endl;
pool.add(std::make_unique<Users>(i, ac_num));
}

{ //{}块
//在这个块里可以通过get()获取到对象池里的对象,每获取一次,会从对象池中删除
cout << "pool size: " <<pool.pool_size() << endl;
auto p1 = pool.get();
cout << p1->index << endl;
auto p2 = pool.get();
cout << p2->index << endl;
cout << "pool size: " << pool.pool_size() << endl;
}
// 到这里,所有对象还是在对象池里,不受前一块的get()的影响
cout << "pool size: " << pool.pool_size() << endl;
// 最后会自动调用析构函数删除所有对象。
return 0;
}

pool_1.png