构想:
基于C++11封装一个简易的对象池,输出使用 std::vector
存储对象成员,对外提供 std::uniqued_ptr
避免忘记销毁,std::uniqued_ptr
释放是自动放回std::vector
的尾部。提供最少的接口:add,用于添加一个成员;get,用于获取一个成员;empty,检查是否为空;size,获取成员数量。参考cosmos老师的源码。
源码:
#pragma once
#include <memory>
#include <vector>
#include <functional>
template <class T>
class simple_object_pool
{
private:
std::vector<std::unique_ptr<T>> pool_;
public:
using deleterType = std::function<void(T*)>;
void add(std::unique_ptr<T> t)
{
pool_.push_back(std::move(t));
}
std::unique_ptr<T, deleterType> get()
{
if (pool_.empty())
{
throw std::logic_error("no more object");
}
//every time add custom deleter for default unique_ptr
//通过std::vector::back()获取最后一个成员的引用;
//通过std::unique_ptr::release()释放所有权,并用一个空指针代替;
//通过std::vector::pop_back()移除最后一个元素;
//指定删除器函数,将对象重新放到std::vector的尾部。
std::unique_ptr<T, deleterType> ptr(pool_.back().release(), [this](T* t)
{
pool_.push_back(std::unique_ptr<T>(t));
});
pool_.pop_back();
return std::move(ptr);
}
std::shared_ptr<T> get_shared()
{
if (pool_.empty())
{
throw std::logic_error("no more object");
}
auto pin = std::unique_ptr<T>(std::move(pool_.back()));
pool_.pop_back();
return std::shared_ptr<T>(pin.release(), [this](T* t)
{
pool_.push_back(std::unique_ptr<T>(t));
});
}
bool empty() const { return pool_.empty(); }
size_t size() const { return pool_.size(); }
};
//test code
// void test_object_pool()
// {
// SimpleObjectPool<A> p;
// p.add(std::unique_ptr<A>(new A()));
// p.add(std::unique_ptr<A>(new A()));
// {
// auto t = p.get();
// p.get();
// }
// {
// p.get();
// p.get();
// }
// std::cout << p.size() << std::endl;
// }
解析:
涉及知识点:
std::unique_ptr::release
释放空间所有权,用空指针代替,不再负责删除;删除的职责交给新的所有者;std::unique_ptr转std::shared_ptr
std::unique_ptr<std::string> unique = std::make_unique<std::string>("test");
std::shared_ptr<std::string> shared = std::move(unique);
或
std::shared_ptr<std::string> shared = std::make_unique<std::string>("test");
std::vector::push_back
:新增一个新成员到尾部std::vector::pop_back
:删除最后一个成员std::function
:指定删除器的函数类型
在www.cplusplus.com中,std::unique_ptr::release的注解如下: Releases ownership of its stored pointer, by returning its value and replacing it with a null pointer.
This call does not destroy the managed object, but the unique_ptr object is released from the responsibility of deleting the object. Some other entity must take responsibility for deleting the object at some point.
To force the destruction of the object pointed, either use member function reset or perform an assignment operation on it.
参考资料:
[stackoverrun] : C++ 11 unique_ptr和shared_ptr能够转换为彼此的类型吗?
http://www.cplusplus.com/reference/vector/vector/ http://www.cplusplus.com/reference/memory/unique_ptr/release/ https://github.com/xuejianhui0911/cosmos/blob/master/object_pool/SimpleObjectPool.hpp