ObjectPool.hpp:
#pragma once #include <string> #include <memory> #include <functional> #include <map> using namespace std; template <typename T> class ObjectPool { template <typename... Args> using Constructor = std::function<std::shared_ptr<T>(Args...)>; public: ~ObjectPool() { destructedFlag = true; } // 默认创建多少个对象 template <typename... Args> void Init(size_t num, Args&&... args) { if (num <= 0) { throw std::logic_error("object num out of range!"); } m_object_map.clear(); auto constructName = typeid(Constructor<Args...>).name(); // 不区分引用 for (size_t i = 0; i < num; i++) { m_object_map.emplace(constructName, std::shared_ptr<T>(new T(std::forward<Args>(args)...), [this, constructName](T* p) { // (析构函数)删除器中不直接删除对象,而是回收到对象池中,以供下一次使用 if (!destructedFlag) // 解决内存中释放的时序造成的野指针,如果ObjectPool对象先释放,T对象后释放,则触发这里emplace会卡死 { m_object_map.emplace(std::move(constructName), std::shared_ptr<T>(p)); } else { delete p; } })); } } // 从对象池中获取一个对象 template <typename... Args> std::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; bool destructedFlag = false; };
测试代码:
#include <iostream> #include <string> #include "ObjectPool.hpp" using namespace std; struct MyObj { MyObj() { cout << "MyObj construct... 0x" << hex << this << endl; } MyObj(int a) { cout << "MyObj construct:" << a << " 0x" << hex << this << endl; } MyObj(const int& a, const int& b) { cout << "MyObj construct a:" << a << " b:" << b << " 0x" << hex << this << endl; } ~MyObj() { cout << "MyObj destruct... 0x" << hex << this << endl; } void print(const string& str) { cout << "print:" << str.c_str() << endl; } }; void printTest(std::shared_ptr<MyObj> p, const string& str) { if (p != nullptr) { p->print(str); } else { cout << "printTest error: p is nullptr..." << endl; } } void TestObjPool() { ObjectPool<MyObj> pool; pool.Init(2); // 初始化两个对象 // 除了下面的作用域,对象又会自动回收 { auto p1 = pool.Get(); printTest(p1, "p1..."); auto p2 = pool.Get(); printTest(p2, "p2..."); cout << "---------------------" << endl; } auto p1 = pool.Get(); auto p2 = pool.Get(); printTest(p1, "p1"); printTest(p2, "p2"); cout << "===========================0" << endl; ObjectPool<MyObj> pool2; pool2.Init(2, 1); // 初始化两个对象,并用1来实例对应的对象构造函数 auto p4 = pool2.Get<int>(); printTest(p4, "p4"); cout << "===========================1" << endl; pool.Init(2, 3, 4); // 初始化两个对象,并用3和4来实例对应的对象构造函数 auto p5 = pool.Get<int, int>(); printTest(p5, "p5"); cout << "===========================2" << endl; } int main(int, char *[]) { TestObjPool(); system("pause"); return 0; }
虽然同一个ObjectPool可以执行多次Init,但所有Init创建的实例,都要在该ObjectPool释放时,才能被释放。
相关推荐
在C++11中,我们可以利用其新引入的特性来实现一个简单的内存池。本项目就是针对这一主题的一个实践,适用于Visual Studio 2015、g++4.8和clang++3.4等编译器。 内存池的基本思想是避免频繁的系统调用,因为传统的...
本篇将深入探讨对象池的概念、工作原理以及如何在C++中实现对象池。 对象池的基本思想是预先创建并维护一组对象,而不是每当需要时就动态地创建新对象,然后在不再需要时再销毁它们。这种策略可以显著减少对象生命...
本资源提供了一个用C++实现的对象池模型,包括了源码,可以帮助开发者深入理解并应用对象池设计模式。 首先,让我们详细探讨对象池的五要素: 1. **对象集合**:这是对象池的核心部分,它存储了所有可复用的对象。...
在C++编程中,内存管理和性能优化是两个关键领域,对于开发高质量、高效能的应用程序至关重要。本主题将深入探讨这两个方面,旨在帮助开发者更好地理解如何编写更优化的C++代码。 内存管理是C++的核心特性之一,...
C++广泛应用于系统软件、应用软件开发、游戏开发、嵌入式系统、高性能服务器和客户端应用程序等领域。 C++的一些关键特性包括: - 面向对象编程:支持类、继承、多态和封装等概念。 - 泛型编程:通过模板支持,允许...
5. **代码注释**:为了帮助理解,Demo案例中的代码会有详细的注释,解释每个步骤的作用和实现方式,帮助开发者更好地理解和应用对象池技术。 通过学习这个Demo,开发者可以了解到如何在实际项目中应用对象池,如何...
在这个"游戏对象池例子(兼容智能指针、工厂类)"中,我们将探讨如何利用C++实现这种技术,并结合智能指针和工厂模式来确保兼容性和效率。 1. **对象池概念**: 对象池的基本思想是预先创建一批对象,当需要对象时...
线性池,也称为对象池或者内存池,是一种内存管理技术,主要应用于程序设计中,尤其是在需要频繁创建和销毁对象的场景下。它的核心思想是预先分配一大块内存,然后根据需要从中分配小块内存,而不是每次都需要向操作...
8. **应用实例**:内存池广泛应用于数据库、网络服务、游戏引擎等领域,这些场景通常涉及到大量小对象的快速创建和销毁。 总的来说,C++对象内存池是一种高效内存管理技术,通过预先分配和统一管理内存,能有效提升...
内存池是一种优化内存分配策略的技术,它在C++编程中被广泛应用,特别是在处理大量小对象分配和释放时,能够显著提升程序性能。本项目提供的是一个自定义实现的C++内存池,包括文档和源代码,旨在帮助理解内存池的...
通过这个C++实例教程和源码,你可以学习到如何在实际项目中应用这些概念,理解多线程编程的挑战和优势,以及如何编写高效的多线程代码。记得实践是检验真理的唯一标准,动手尝试这些示例,将有助于你更好地掌握C++的...
std::allocator 是 C++标准库中提供的默认分配器,他的特点就在于我们在 使用 new 来申请内存构造新对象的时候,势必要调用类对象的默认构造函数 而使用 std::allocator 则可以将内存分配和对象的构造这两部分...
7. **性能优化**:C++ 驱动允许进行一些性能优化,比如批量操作、连接池管理、异步操作等,这有助于提高应用程序的整体性能。 8. **安全注意事项**:在实际应用中,确保正确处理用户输入,防止 SQL 注入攻击,并且...
在这个“C++面向对象程序设计 游泳池”实验中,我们将探讨如何利用C++的OOP特性来构建一个模拟游泳池的类结构。 首先,我们需要定义“游泳池”这个类。类是OOP中的核心构造块,它封装了数据(成员变量)和行为...
在C/C++编程中,内存池常用于频繁创建和销毁小对象的场景,如网络编程、数据库连接等。本文将深入探讨几种内存池的实现方式及其源码分析。 1. **静态内存池**: 静态内存池在程序启动时就分配好内存,且在程序运行...
COM+事件系统使得组件间的异步通信更加简单,对象池提高了组件创建和销毁的效率,自动事务处理确保了操作的原子性,线程模型则提供了多种多线程处理策略以适应不同的应用场景。 此外,COM+还引入了服务组件...
在Linux环境下,C/C++开发数据库连接池是提高应用程序性能和效率的重要技术。数据库连接池是一种管理数据库连接的机制,它允许程序重复使用已建立的数据库连接,而不是每次需要时都创建新的连接。这减少了创建和销毁...
在IT行业中,内存管理是程序设计中的重要环节,尤其是在C++这种低级语言中,对内存的精细控制能显著提高程序的...深入理解并合理应用内存池,能够提升C++程序的性能和稳定性,是每个C++程序员应该掌握的高级技巧之一。
内存池是一种优化内存分配策略的技术,它在C++编程中被广泛应用,特别是在处理大量小对象分配和释放时,能够显著提高性能并减少内存碎片。内存池的基本思想是预先分配一大块连续的内存,并通过自己的管理机制来分配...
总之,C++的面向对象特性和多线程支持使得开发者能够构建复杂、高效的应用程序。通过熟练掌握这些概念和实践,你将在软件开发领域更上一层楼。在实际项目中,要始终考虑线程安全、性能优化以及代码的可读性和可维护...