c++11设计模式 对象池模式 可变参数构造 自动析构

当程序中需要用到一定数量的对象,且创建对象开销比较大时可以考虑使用对象池模式。和线程池类型,需要预先创建一定数量的对象,上层使用时可以从池子中获取创建好的对象。本文的对象池模式实现可变参数构造对象,使用完成之后自动析构。

#include 
#include 
#include 
#include 
#include 

constexpr int kMaxObjectNum = 10;

template<typename T>
class ObjectPool {
 public:
     ObjectPool(int max_object_num = kMaxObjectNum)
        : max_object_num_(max_object_num) {}

    template<typename...Args>
    bool Init(size_t const object_num, Args&&...args) {
        if (object_num <=0 || object_num > max_object_num_) {
            return false;
        }
        auto obj_name = typeid(ObjectType<Args...>).name();
        for (size_t i = 0; i < object_num; i++) {
            objects_map_.emplace(obj_name,
                std::shared_ptr<T>(new T(std::forward<Args>(args)...)));
        }
        return true;
    }

    template<typename...Args>
    std::shared_ptr<T> GetObj() {
        auto object_name = typeid(ObjectType<Args...>).name();
        auto range = objects_map_.equal_range(object_name);
        for (auto it = range.first; it != range.second; it++) {
            return it->second;
        }
        return nullptr;
    }

 private:
    template<typename...Args>
    using ObjectType = std::function<std::shared_ptr<T>(Args...)>;

    std::multimap<std::string, std::shared_ptr<T>> objects_map_;
    int max_object_num_;
};

ObjectPool类使用multimap保存创建的对象,使用构造函数对作为key来获取对应的对象。
Init接口会根据传入的参数object_num来设定创建对象的数量,如果不在范围内直接返回false。根据传入的构造参数创建对应的对象,并通过智能指针保存到objects_map_中,可以确保在析构的时候没有内存泄露。
GetObj接口依据传入的参数来返回对应的对象的智能指针,找不到对应对象时,返回nullptr。
开始测试

class Object {
 public:
    Object(): data1_(0), data2_(0) {}
    Object(int a) : data1_(a), data2_(0) {}
    Object(const int& a, const int& b) : data1_(a), data2_(b){}

    void Run(const std::string& str) {
        std::cout << str << std::endl;
        std::cout << "data1:" << data1_ << std::endl;
        std::cout << "data2:" << data2_ << std::endl;
    }

 private:
    int data1_;
    int data2_;
};

void Task(std::shared_ptr<Object> obj, const std::string& str) {
    if (nullptr != obj) {
        obj->Run(str);
    }
}

int main() {
    ObjectPool<Object> pool;
    if (!pool.Init(2)) {
        std::cout << "Init failed" << std::endl;
        return -1;
    }
    auto object1 = pool.GetObj();
    Task(object1, "object1");

    object1 = pool.GetObj();
    Task(object1, "object1");

    if (!pool.Init(2, 15)) {
        std::cout << "Init failed" << std::endl;
        return -1;
    }
    auto object2 = pool.GetObj<int>();
    Task(object2, "object2");

    if (!pool.Init(2, 10, 20)) {
        std::cout << "Init failed" << std::endl;
        return -1;
    }
    auto object3 = pool.GetObj<int, int>();
    Task(object3, "object3");
    return 0;
}

输出:

object1
data1:0
data2:0
object1
data1:0
data2:0
object2
data1:15
data2:0
object3
data1:10
data2:20

你可能感兴趣的:(设计模式,编程)