gpt4 book ai didi

c++ - unique_ptr 的有状态自定义删除器

转载 作者:行者123 更新时间:2023-11-28 01:18:53 43 4
gpt4 key购买 nike

我正在使用内存池来加快分配和释放速度。内存池的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++ - unique_ptr 的有状态自定义删除器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57622488/

43 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com