C++小碗菜

13k 词

一些C++中经常会接触的小组件,包括中间件,STL等

但这些内容都只实现了基本功能,实际运用的时候可能还需要根据具体需求进行扩展和优化

内存池 Memory Pool

内存池是一种预先分配一大块内存,然后按需分配小块内存的技术

内存池可以减少频繁的内存分配和释放操作从而提高性能

用一个栈实现:

classDiagram
    class MemoryPool {
        char* _pool
        size_t _objectsize
        size_t _totalsize
        stack~void*~ _freelist
        void* allocate()
        void deallocate(void* ptr)
    }

    MemoryPool --* "1" char : 管理
    MemoryPool --* "1" stack : 包含

    class FreeListStack {
        <>
        void*类型
        push(void* ptr)
        pop() void*
        top() void*
        empty() bool
    }

    MemoryPool --> FreeListStack : 使用
flowchart TD
    A[开始] --> B{根据类型创建内存池}
    B -->|分配| C[调用 allocate]
    B -->|释放| D[调用 deallocate]

    C --> E{_freelist为空?}
    E -->|是| F[抛出 bad_alloc]
    E -->|否| G[从栈顶取指针]
    G --> H[返回指针]

    D --> I[指针压入栈]
    I --> J[返回]

    F --> K[结束]
    H --> K
    J --> K

如果是多线程的情况,需要在用户应用层进行线程安全的一系列操作

共享指针 Shared Pointer

shared_ptr(共享智能指针)是C++标准库提供的一种智能指针,用于自动管理动态分配的内存资源。它采用引用计数机制,记录有多少个shared_ptr指向同一个对象。当最后一个shared_ptr被销毁或重置时,其所管理的对象会被自动删除,从而有效防止内存泄漏。shared_ptr支持拷贝和赋值操作,允许多个指针共享同一资源。使用shared_ptr能简化资源生命周期管理,是现代C++中避免原始指针风险的重要工具。

这里用一个struct块来模拟引用计数,实际上也可以直接用一个int*来替代。

classDiagram
    class MySharedPtr~T~ {
        T* ptr
        controlblock* ctrl_blk
        void Release()
        int use_count() const
        T* get() const
        void reset(T* p)
    }

    class controlblock {
        int count_ref
        controlblock()
    }

    MySharedPtr --o controlblock : 拥有
    MySharedPtr --> T : 管理

函数封装 Function Encapsulation

四种函数封装方式

  1. 函数指针
  2. 仿函数(函数对象)
  3. std::function
  4. lambda表达式
  • 性能敏感场景:优先考虑函数指针或模板仿函数
  • 回调系统:使用std::function统一接口
  • 局部算法:lambda表达式最合适
  • 兼容C代码:必须使用函数指针

双向链表容器 List

有节点定义,迭代器类和容器类

双端队列容器 Deque


deque 通常由一系列固定大小的数组块组成,这些块通过一个中央数组进行管理
整个结构使得在两端扩展的时候不需要再重新分配整个容器的内存

简化版:环形缓冲区deque

支持随机访问元素
支持在两端频繁插入和删除元素