C++ 11实现对象池

技术原理,

  1. 使用std::shared_ptr的删除函数,在对象析构时,将对象退还回对象池的multimap中
  2. 使用可变参数实现任意对象的构造

代码如下,
noncopyable.hpp

#ifndef _NONCOPYABLE_HPP_
#define _NONCOPYABLE_HPP_

class NonCopyable {
    public:
        NonCopyable(const NonCopyable& n) = delete; // deleted
        NonCopyable& operator=(const NonCopyable& n) = delete; // deleted
        NonCopyable() = default; // available
};
#endif

object_pool.hpp

#include <string>
#include <functional>
#include <memory>
#include <map>
#include "noncopyable.hpp"
using std::string;
using std::shared_ptr;
using std::multimap;

const int MaxObjectNum = 10;

template <typename T>
class ObjectPool: public NonCopyable {
    template <typename ... Args>
    // 输入为Args类型,返回为std::shared_ptr<T>类型的函数
    using Constructor = std::function<shared_ptr<T>(Args...)>;
    public:

        // 初始化对象池
        template <typename ... Args> 
        void Init(size_t num, Args &&... args) {
            if(num <= 0 || num > MaxObjectNum) {
                throw std::logic_error("object num out of range");
            }

            auto constructorName = typeid(Constructor<Args...>).name();
            for(size_t i=0; i < num; ++i) {
                m_object_map.emplace(constructorName, shared_ptr<T>(new T(std::forward<Args>(args)...),
                    [this, constructorName] (T* p){  // 删除器中回收到对象池,供下次使用,删除时used_count-1,使用p构造一个新的,令used_count + 1
                        m_object_map.emplace(std::move(constructorName), shared_ptr<T>(p));                      
                    } ));
            }
        }

        // 从对象池中获取一个对象
        template <typename ... Args>
        shared_ptr<T> Get() {
            string constructName = typeid(Constructor<Args...>).name();
            auto range = m_object_map.equal_range(constructName);
            for(auto it = range.first; it != range.second; it++) {
                auto ptr = it->second;
                m_object_map.erase(it);
                return ptr;
            }
            return nullptr;
        }

    private:
        multimap<string, std::shared_ptr<T> > m_object_map;
};  

main.cpp

#include "object_pool.hpp"
#include <iostream>
using std::cout;
using std::endl;

// MySQL连接器类
class MySQLConn: NonCopyable {
    public:
        MySQLConn(string url, string username, string password): mURL(url), mUser(username), mPass(password) {}

        void ExecSQL(const string& sql) {
            cout << "Exec: [" << sql << "]" << endl;
        }

    private:    
        MySQLConn() = delete;
        string mURL;
        string mUser;
        string mPass;
};

int main() {
    ObjectPool<MySQLConn> p;
    p.Init(5, "jdbc:mysql", "root", "root");
    shared_ptr<MySQLConn> conn = p.Get();
    conn->ExecSQL("insert into stu(id, name, score) values(1, '张三', 78.5);");
    
}

Makefile

TAR=main
WORKSPACE_DIR=.
CC:=g++

.PHONY: build clear all

build:
    $(CC) -std=c++11 $(WORKSPACE_DIR)/*.*pp -g -o $(TAR)

all: clear build

clear:
    rm -rf $(TAR)

程序输出如下


图片.png
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容