unique_ptr、自定义删除程序和零法则
unique_ptr, custom deleter, and Rule of Zero
我正在编写一个使用使用 C 接口创建的两个对象的类。对象如下所示:
typedef struct... foo_t;
foo_t* create_foo(int, double, whatever );
void delete_foo(foo_t* );
(同样适用于bar_t
)。因为 C++11,我想将它们包装在一个智能指针中,这样我就不必编写任何特殊方法。该类将拥有两个对象的唯一所有权,因此unique_ptr
逻辑上是有意义的......但我仍然必须编写一个构造函数:
template <typename T>
using unique_ptr_deleter = std::unique_ptr<T, void(*)(T*)>;
struct MyClass {
unique_ptr_deleter<foo_t> foo_;
unique_ptr_deleter<bar_t> bar_;
MyClass()
: foo_{nullptr, delete_foo}
, bar_{nullptr, delete_bar}
{ }
~MyClass() = default;
void create(int x, double y, whatever z) {
foo_.reset(create_foo(x, y, z));
bar_.reset(create_bar(x, y, z));
};
另一方面,使用 shared_ptr
,我不必编写构造函数或使用类型别名,因为我可以将delete_foo
传入 reset()
- 尽管这将使我的MyClass
可复制,我不希望这样。
使用unique_ptr
语义编写MyClass
并仍然遵守零规则的正确方法是什么?
你的类不需要声明析构函数(无论你是否声明它为默认值,它都会得到正确的默认实现),所以仍然遵守"零规则"。
但是,您可以通过使删除器函数对象而不是指针来改善这一点:
template <typename T> struct deleter;
template <> struct deleter<foo_t> {
void operator()(foo_t * foo){delete_foo(foo);}
};
template <> struct deleter<bar_t> {
void operator()(bar_t * bar){delete_bar(bar);}
};
template <typename T>
using unique_ptr_deleter = std::unique_ptr<T, deleter<T>>;
这有几个好处:
unique_ptr
不需要存储额外的指针- 删除函数可以直接调用,而不是通过指针调用
- 你不需要编写构造函数;默认构造函数将做正确的事情。
相关文章:
- 共享指针和具有自定义删除程序的唯一指针之间的语法差异背后的任何原因
- 在unique_ptr<>中使用自定义删除程序 (curl_formfree())
- shared_ptr的删除程序是否存储在自定义分配器分配的内存中?
- 用于unique_ptr的有状态自定义删除程序
- 为什么unique_ptr不能阻止自定义删除程序的切片?
- std::unique_ptr 和自定义删除程序
- 如何使用lambda和函数作为unique_ptr的自定义删除程序
- std::unique_ptr,自定义删除程序和类型更改
- shared_ptr<EVP_PKEY> EVP_PKEY_free作为自定义删除程序会导致堆损坏
- 使用自定义删除程序返回unique_ptr的 nullptr 失败
- 对 Direct3D11 对象上使用 std::shared_ptr 的自定义删除程序
- 为shared_ptr但遇到错误指定自定义删除程序
- unique_ptr、自定义删除程序和零法则
- 带有自定义删除程序错误的 c++ 唯一指针
- 使用外部定义的自定义删除程序在头文件中定义唯一指针
- 类成员唯一指针,具有初始值设定项列表外部的自定义删除程序
- 标准::shared_ptrs的自定义删除程序
- 何时对 std::shared_ptr 使用自定义删除程序
- 如何用c++编写自定义卸载程序代码,用于在Visual Studio 2008中删除用户生成的文件
- std::map 不删除带有自定义对象的重复项