作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我使用RAII样式的智能对象池,并且想要将获取的对象设置为另一个类的成员。
T.C.建议的智能对象池:
template <class T, class D = std::default_delete<T>>
class SmartObjectPool
{
private:
struct ReturnToPool_Deleter {
explicit ReturnToPool_Deleter(std::weak_ptr<SmartObjectPool<T, D>* > pool) : pool_(pool) {
}
void operator()(T* ptr) {
if (auto pool_ptr = pool_.lock())
(*pool_ptr.get())->add(std::unique_ptr<T, D>{ptr});
else
D{}(ptr);
}
private:
std::weak_ptr<SmartObjectPool<T, D>* > pool_;
};
public:
using ptr_type = std::unique_ptr<T, ReturnToPool_Deleter >;
SmartObjectPool() : this_ptr_(new SmartObjectPool<T, D>*(this)) {}
virtual ~SmartObjectPool(){}
void add(std::unique_ptr<T, D> t) {
pool_.push(std::move(t));
}
ptr_type acquire() {
if (pool_.empty())
throw std::out_of_range("Cannot acquire object from an empty pool.");
ptr_type tmp(pool_.top().release(),
ReturnToPool_Deleter{
std::weak_ptr<SmartObjectPool<T, D>*>{this_ptr_}});
pool_.pop();
return std::move(tmp);
}
bool empty() const {
return pool_.empty();
}
size_t size() const {
return pool_.size();
}
private:
std::shared_ptr<SmartObjectPool<T, D>* > this_ptr_;
std::stack<std::unique_ptr<T, D> > pool_;
};
class Setter {
public:
void setValue(SmartObjectPool<int>::ptr_type value) {
m_value = std::move(value);
}
private:
SmartObjectPool<int>::ptr_type m_value;
};
int main()
{
SmartObjectPool<int> pool;
pool.add(std::make_unique<int>());
assert(pool.size() == 1u);
{
auto obj = pool.acquire();
Setter setter;
setter.setValue(std::move(obj));
assert(pool.size() == 0u);
}
assert(pool.size() == 1u);
auto obj = pool.acquire();
return 0;
}
In file included from /usr/include/c++/5/functional:55:0,
from /usr/include/c++/5/memory:79,
from src/main.cpp:1:
/usr/include/c++/5/tuple: In instantiation of ‘constexpr std::_Head_base<_Idx, _Head, false>::_Head_base() [with long unsigned int _Idx = 1ul; _Head = SmartObjectPool<int>::ReturnToPool_Deleter]’:
/usr/include/c++/5/tuple:353:15: required from ‘constexpr std::_Tuple_impl<_Idx, _Head>::_Tuple_impl() [with long unsigned int _Idx = 1ul; _Head = SmartObjectPool<int>::ReturnToPool_Deleter]’
/usr/include/c++/5/tuple:202:29: required from ‘constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl() [with long unsigned int _Idx = 0ul; _Head = int*; _Tail = {SmartObjectPool<int>::ReturnToPool_Deleter}]’
/usr/include/c++/5/tuple:602:20: required from ‘constexpr std::tuple<_T1, _T2>::tuple() [with _T1 = int*; _T2 = SmartObjectPool<int>::ReturnToPool_Deleter]’
/usr/include/c++/5/bits/unique_ptr.h:158:14: required from ‘constexpr std::unique_ptr<_Tp, _Dp>::unique_ptr() [with _Tp = int; _Dp = SmartObjectPool<int>::ReturnToPool_Deleter]’
src/main.cpp:59:7: required from here
/usr/include/c++/5/tuple:105:22: error: no matching function for call to ‘SmartObjectPool<int>::ReturnToPool_Deleter::ReturnToPool_Deleter()’
: _M_head_impl() { }
^
src/main.cpp:11:22: note: candidate: SmartObjectPool<T, D>::ReturnToPool_Deleter::ReturnToPool_Deleter(std::weak_ptr<SmartObjectPool<T, D>*>) [with T = int; D = std::default_delete<int>]
explicit ReturnToPool_Deleter(std::weak_ptr<SmartObjectPool<T, D>* > pool)
^
src/main.cpp:11:22: note: candidate expects 1 argument, 0 provided
src/main.cpp:10:16: note: candidate: SmartObjectPool<int>::ReturnToPool_Deleter::ReturnToPool_Deleter(const SmartObjectPool<int>::ReturnToPool_Deleter&)
struct ReturnToPool_Deleter {
^
src/main.cpp:10:16: note: candidate expects 1 argument, 0 provided
src/main.cpp:10:16: note: candidate: SmartObjectPool<int>::ReturnToPool_Deleter::ReturnToPool_Deleter(SmartObjectPool<int>::ReturnToPool_Deleter&&)
src/main.cpp:10:16: note: candidate expects 1 argument, 0 provided
src/main.cpp: In function ‘int main()’:
src/main.cpp:87:10: note: synthesized method ‘constexpr Setter::Setter()’ first required here
Setter setter;
^
Makefile:17: recipe for target 'obj/main.o' failed
make: *** [obj/main.o] Error 1
最佳答案
问题在于以下几行
Setter setter;
Setter
,但
Setter
并非默认构造。默认的
Setter
构造函数被隐式删除,因为它具有一个
SmartObjectPool<int>::ptr_type
成员,该成员本身不是默认可构造的。
SmartObjectPool<int>::ptr_type
是
std::unique_ptr<T, ReturnToPool_Deleter >
的别名。现在,让我们看看
cppreference对
std::unique_ptr<T, Deleter>
的默认构造函数有什么要说的。
1) Constructs a std::unique_ptr that owns nothing. Value-initializes the stored pointer and the stored deleter. Requires that Deleter is DefaultConstructible and that construction does not throw an exception.
unique_ptr
是默认可构造的,则只能默认构造
Deleter
,在您的情况下,这是不正确的:
ReturnToPool_Deleter
不是默认可构造的。
using Deleter = std::function<void(T* ptr)>;
using ptr_type = std::unique_ptr<T, Deleter>;
auto deleter = [pool_ = std::weak_ptr<SmartObjectPool<T, D>*>{this_ptr_} ](T* ptr) {
if (auto pool_ptr = pool_.lock()) {
(*pool_ptr.get())->add(std::unique_ptr<T, D>{ptr});
} else {
D{}(ptr);
}
};
ptr_type tmp(pool_.top().release(), deleter);
关于c++ - 如何在C++中设置从RAII样式智能对象池获取的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61340688/
我是一名优秀的程序员,十分优秀!