有人可以建议如何使用自定义deletor从templatised唯一指针池返回唯一指针。
在下面的代码片段中,我使用ObjectPool.h作为我的模板类来获取一堆独特的指针。 我正在使用ObjectPool在DBConnection.h中创建一个sharedpool对象,稍后在DBConnection.cpp中我只是将对象返回到DBExec。
我在DBConnection.cpp中遇到与将删除指针转换为普通唯一指针相关的编译错误。
> Class that will manage connection objects.
**DBConnectionPool.h**
#ifndef DBCONNECTIONPOOL_H
#define DBCONNECTIONPOOL_H
#include "DBExec.h"
#include "ObjectPool.h"
class DBConnectionPool {
static SharedPool<DBExec> pool;
static DBConnectionPool* instance;
DBConnectionPool& operator=(const DBConnectionPool&);
DBConnectionPool(const DBConnectionPool&);;
DBConnectionPool(){};
public:
...
**static std::unique_ptr<DBExec> getQueryObject();**
};
#endif /* DBCONNECTIONPOOL_H */
**DBConnection.cpp**
>implementation of getQueryObject
**std::unique_ptr<DBExec> DBConnectionPool::getQueryObject() {
return std::move(pool.acquire());
}**
/* Class that manages the unique pointer */
**ObjectPool.h**
#ifndef OBJECTPOOL_H
#define OBJECTPOOL_H
#include <memory>
#include <stack>
#include <mutex>
#include <assert.h>
template <class T>
class SharedPool {
/* Class that manages the unique pointer */
public:
using ptr_type = std::unique_ptr<T, std::function<void(T*)> >;
SharedPool() {
}
virtual ~SharedPool() {
}
void add(std::unique_ptr<T> t) {
std::lock_guard<std::mutex> lck (mt);
pool_.push(std::move(t));
}
ptr_type acquire() {
std::lock_guard<std::mutex> lck (mt);
assert(!pool_.empty());
ptr_type tmp(pool_.top().release(),
[this](T * ptr) {
this->add(std::unique_ptr<T>(ptr));
});
pool_.pop();
return std::move(tmp);
}
bool empty() const {
std::lock_guard<std::mutex> lck (mt);
return pool_.empty();
}
size_t size() const {
std::lock_guard<std::mutex> lck (mt);
return pool_.size();
}
std::stack<std::unique_ptr<T>>& getPoolStack () {
return pool_;
}
private:
> thread safe
std::mutex mt;
std::stack<std::unique_ptr<T> > pool_;
};
#endif /* OBJECTPOOL_H */
答案 0 :(得分:1)
std::unique_ptr<T,D>
和std::unique_ptr<T>
是不相关的类型(除非D=std::default_delete<T>
)。因此,您需要在所有typedef中指定删除器的类型。
接下来的问题是你无法实际输入删除器的类型,因为它是lambda类型。因此,您可能必须从lambda切换到命名的可调用类型。
template <class T>
class SharedPool {
public:
class Deleter {
public:
void operator()(T* ptr) const {
pool->add(std::unique_ptr<T,Deleter>(ptr));
}
private:
explicit Deleter(SharedPool* pool) : pool(pool) {}
SharedPool* pool;
friend class SharedPool<T>;
};
using ptr_type = std::unique_ptr<T, Deleter>;
您也可以考虑使用std::shared_ptr
,因为它会删除其删除类型,但您似乎不需要共享。
答案 1 :(得分:1)
如果我理解正确,您希望从具有自定义删除功能的常规unique_ptr
获取。这是不可能的,因为从另一个unique_ptr
返回unique_ptr
会违反该指针的唯一性。你唯一的选择是将它转换成某种东西,删除器是从类型中隐藏的(即类型擦除)。
答案 2 :(得分:0)
听起来你想要的是类型擦除,或至少部分类型擦除。一个简单的解决方案就是使用std::shared_ptr
:
std::shared_ptr<T>(new T, custom_deleter);
这将提供超过std::unique_ptr
的一些开销,但有些开销是不可避免的。