unique_ptr 的删除器
Deleters for unique_ptr
有一个包含唯一指针的数组:
std::array<std::unique_ptr<T, deleter<allocator<T>>>> storage;
哪里
template<typename ALLOC>
class deleter {
void operator()( void ) { ... }
};
按照unique_ptr的要求进行删除。实际上,它调用析构函数,然后释放占用的内存。到目前为止一切顺利。
但是还有一个删除器:
template<typename T>
class empty_deleter {
void operator()( void ) {}
};
它根本不执行任何操作 - 没有销毁,没有释放。
它存在的原因是理论上可以选择在存储阵列中存储此类 unique_ptr<T, empty_deleter<T>>
拥有的对象...
问题是 - 如何实现?为了使删除器兼容,以便我可以将 unique_ptr<T, empty_deleter<T>>
分配给 unique_ptr<T, deleter<allocator<T>>>
指针数组...
我知道 unique_ptr
实现中有转换构造函数,所以理论上,一种类型的删除器可以分配给用另一种类型声明的 unique_ptr
但这些删除器有一个约束应该可以以某种方式转换...你能告诉我如何实现吗?
此外 - 一旦我成功地将 empty_deleter<T>
的删除器实例分配给 unique_ptr<T, deleter<allocator<T>>>
无论如何,触发删除后将调用哪个 operator()
?来自 empty_deleter<T>
或 deleter<allocator<T>>
?
的那个
您只需 release
从一个对象获取指针并将其传递给另一个对象即可。这两种类型在设计上 不兼容。你不应该让它们兼容,所以你必须做这个奇怪的事情才能让它工作。
是的,您可以通过使 deleter
可从 empty_deleter
构造和分配来完成这项工作。但这很糟糕,因为它在逻辑上没有任何意义。
unique_ptr
应该 拥有该对象; 就是这样。你不应该想要拥有一个非拥有者unique_ptr
。如果有人得到 unique_ptr
,那应该意味着他们 拥有 那东西。
更糟糕的是,采用非拥有指针并声称拥有它的想法本身 非常可疑 。如果一段代码没有删除某些东西的权利(这就是类型unique_ptr<T, empty_deleter<T>>
应该是什么意思),它也没有权利委托责任将它删除给其他人。
您尝试编写的代码对于谁拥有什么(甚至“拥有”一个对象意味着什么)非常不清楚,应该重新考虑。
正如@Nicol Bolas 指出的那样,“unique_ptr<T, empty_deleter<T>>
拥有的对象”是荒谬的。我会回答“如何制作一个有时拥有有时不拥有它的指针对象的智能指针”。
std::unique_ptr<T, empty_deleter<T>>
、std::unique_ptr<T, deleter<allocator<T>>>
和 std::unique_ptr<T, deleter<other_allocator<T>>>
中的 None 不可相互分配。
如果你想混合和匹配你的指针的所有权,你将不得不类型擦除删除器。最简单的方法是使用现有的函数-对象类型-擦除类型,std::function
.
template <typename T>
class pmr_unique_ptr : public std::unique_ptr<T, std::function<void(T *)>> {
public:
using unique_ptr::unique_ptr;
// have to supply a deleter
pmr_unique_ptr(pointer) = delete;
pmr_unique_ptr() = delete;
pmr_unique_ptr(std::nullptr_t) = delete;
};
这可以从 std::unique_ptr<T, D>
构造,只要 D
是可复制的。
有一个包含唯一指针的数组:
std::array<std::unique_ptr<T, deleter<allocator<T>>>> storage;
哪里
template<typename ALLOC>
class deleter {
void operator()( void ) { ... }
};
按照unique_ptr的要求进行删除。实际上,它调用析构函数,然后释放占用的内存。到目前为止一切顺利。
但是还有一个删除器:
template<typename T>
class empty_deleter {
void operator()( void ) {}
};
它根本不执行任何操作 - 没有销毁,没有释放。
它存在的原因是理论上可以选择在存储阵列中存储此类 unique_ptr<T, empty_deleter<T>>
拥有的对象...
问题是 - 如何实现?为了使删除器兼容,以便我可以将 unique_ptr<T, empty_deleter<T>>
分配给 unique_ptr<T, deleter<allocator<T>>>
指针数组...
我知道 unique_ptr
实现中有转换构造函数,所以理论上,一种类型的删除器可以分配给用另一种类型声明的 unique_ptr
但这些删除器有一个约束应该可以以某种方式转换...你能告诉我如何实现吗?
此外 - 一旦我成功地将 empty_deleter<T>
的删除器实例分配给 unique_ptr<T, deleter<allocator<T>>>
无论如何,触发删除后将调用哪个 operator()
?来自 empty_deleter<T>
或 deleter<allocator<T>>
?
您只需 release
从一个对象获取指针并将其传递给另一个对象即可。这两种类型在设计上 不兼容。你不应该让它们兼容,所以你必须做这个奇怪的事情才能让它工作。
是的,您可以通过使 deleter
可从 empty_deleter
构造和分配来完成这项工作。但这很糟糕,因为它在逻辑上没有任何意义。
unique_ptr
应该 拥有该对象; 就是这样。你不应该想要拥有一个非拥有者unique_ptr
。如果有人得到 unique_ptr
,那应该意味着他们 拥有 那东西。
更糟糕的是,采用非拥有指针并声称拥有它的想法本身 非常可疑 。如果一段代码没有删除某些东西的权利(这就是类型unique_ptr<T, empty_deleter<T>>
应该是什么意思),它也没有权利委托责任将它删除给其他人。
您尝试编写的代码对于谁拥有什么(甚至“拥有”一个对象意味着什么)非常不清楚,应该重新考虑。
正如@Nicol Bolas 指出的那样,“unique_ptr<T, empty_deleter<T>>
拥有的对象”是荒谬的。我会回答“如何制作一个有时拥有有时不拥有它的指针对象的智能指针”。
std::unique_ptr<T, empty_deleter<T>>
、std::unique_ptr<T, deleter<allocator<T>>>
和 std::unique_ptr<T, deleter<other_allocator<T>>>
中的 None 不可相互分配。
如果你想混合和匹配你的指针的所有权,你将不得不类型擦除删除器。最简单的方法是使用现有的函数-对象类型-擦除类型,std::function
.
template <typename T>
class pmr_unique_ptr : public std::unique_ptr<T, std::function<void(T *)>> {
public:
using unique_ptr::unique_ptr;
// have to supply a deleter
pmr_unique_ptr(pointer) = delete;
pmr_unique_ptr() = delete;
pmr_unique_ptr(std::nullptr_t) = delete;
};
这可以从 std::unique_ptr<T, D>
构造,只要 D
是可复制的。