用于unique_ptr的有状态自定义删除程序
Stateful custom deleter for unique_ptr
我正在使用内存池来加快分配和发布速度。内存池的Release()
操作需要要释放的指针和分配的字节数。
现在我想将从内存池获得的数组指针存储在unique_ptr
中。数组的大小是可变的,所以我需要一个有状态的自定义删除器来存储数组的大小。
您能否提供有关如何声明此类unique_ptr
的示例代码?
更新:在Artyer向我明确表示的提示之后,这是我尝试过的:
template<typename T> struct MPSingleDeleter {
void operator()(T *p) {
p->~T();
MemPool::Instance().Release(p, sizeof(T));
}
};
template<typename T> struct MPArrayDeleter {
size_t _nItems;
explicit MPArrayDeleter(const size_t nItems) : _nItems(nItems) {
}
void operator()(T *p) {
for (size_t i = 0; i < _nItems; i++) {
p[i].~T();
}
MemPool::Instance().Release(p, _nItems * sizeof(T));
}
};
template <typename T> using SingleUP = std::unique_ptr<T, MPSingleDeleter<T>>;
template <typename T> using ArrayUP = std::unique_ptr<T[], MPArrayDeleter<T>>;
struct MemHelper {
template<typename T, typename ...Args> static T* NewSingle(Args&&... args) {
void * const p = MemPool::Instance().Acquire(sizeof(T));
::new (p) T(std::forward<Args>(args)...);
return static_cast<T*>(p);
}
template<typename T, typename ...Args> static T* NewArray(const size_t nItems, Args&&... args) {
T *p = static_cast<T*>(MemPool::Instance().Acquire(nItems * sizeof(T)));
for (size_t i = 0; i < nItems; i++) {
void * const pv = static_cast<void *>(p + i);
::new (pv) T(std::forward<Args>(args)...);
}
return p;
}
template<typename T, typename ...Args> static SingleUP<T> MakeSUP(Args&&... args) {
return SingleUP<T>(NewSingle<T>(std::forward<Args>(args)...));
}
template<typename T, typename ...Args> static ArrayUP<T> MakeAUP(const size_t nItems, Args&&... args) {
return ArrayUP<T>(NewArray<T>(nItems, std::forward<Args>(args)...), MPArrayDeleter<T>(nItems));
}
};
现在,unique_ptr
变量的声明非常简单:
// Array of double
ArrayUP<double> pBuffer = MemHelper::MakeAUP<double>(2ui64 * nItems);
// Single Connection
SingleUP<Connection> pConn = MemHelper::MakeSUP<Connection>(ioContext);
您通常会将分配的数据之前的大小存储在内存池中,因此您只需传递一个从指针获取大小的无状态删除器。
不过,您可以轻松地执行以下操作:
#include <memory>
struct pool_deleter {
std::size_t size;
template<class T>
void operator()(T* ptr) noexcept {
std::destroy_n(ptr, size);
Release(ptr, size * sizeof(T));
}
};
template<class T>
using pool_ptr = std::unique_ptr<T, pool_deleter>;
// Used like:
std::size_t n = /* ... */;
T* ptr_ = /* Allocate and construct n objects from pool */;
pool_ptr<T> ptr{ptr_, pool_deleter{n}}; // Pass the custom deleter as an argument
相关文章:
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 如何将点击的信号和插槽添加到qt中的自定义按钮中
- C++自定义比较函数
- 如何比较自定义类的std::变体
- std::设置自定义比较器
- 如何正确实现和访问运算符的各种自定义枚举器
- flutter:即使shouldRepaint()返回true,自定义画家也不会重新绘制
- 自定义先决条件对移动分配运算符有效吗
- 使用VS Code和CMake Tools运行自定义命令
- 如何创建从Maya(或类似程序)到虚幻引擎的自定义数据导出插件
- std::ranges::elements_view,用于自定义类似元组的数据
- 用于unique_ptr的有状态自定义删除程序
- C++ grpc::experimental:interceptor 如何从自定义拦截器返回状态和消息
- 如何在 Tensorflow C++ 中定义变量的自定义有状态 Op 保存值
- 如何将自定义分配器的完全相同状态传递给多个容器?
- 从状态内的自定义函数(不是操作)提升 MSM 调用process_event?
- 如何使用预先定义的状态创建自定义快速QML项目
- 我可以使用boost.statecharts自定义对不同正交区域中多个状态的事件做出反应吗?
- 编写自定义纯虚拟处理程序:调用堆栈和寄存器时的状态是什么
- 正确确定自定义绘制的复选框状态