[英]unique_ptr, custom deleter, and Rule of Zero
I am writing a class that uses two objects created using a C interface. 我正在编写一个使用C接口创建的两个对象的类。 The objects look like: 对象看起来像:
typedef struct... foo_t;
foo_t* create_foo(int, double, whatever );
void delete_foo(foo_t* );
(similarly for bar_t
). (类似于bar_t
)。 Because C++11, I want to wrap these in a smart pointer so I don't have to write any of the special methods. 因为C ++ 11,我想将它们包装在智能指针中,所以我不必编写任何特殊方法。 The class will have unique ownership of the two objects, so unique_ptr
logically make sense... but I would still have to write a constructor: 该类将拥有这两个对象的唯一所有权,因此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));
};
On the flip side, with shared_ptr
, I wouldn't have to write a constructor, or use a type alias, since I could just pass in delete_foo
into reset()
- although that would make my MyClass
copyable and I don't want that. 另一方面,使用shared_ptr
,我不必编写构造函数,或者使用类型别名,因为我可以将delete_foo
传递给reset()
- 尽管这会使我的MyClass
复制而我不希望这样。
What is the correct way to write MyClass
using unique_ptr
semantics and still adhere to Rule of Zero? 使用unique_ptr
语义编写MyClass
的正确方法是什么,仍然遵循Zero of Zero?
Your class doesn't need to declare a destructor (it will get the correct default implementation whether or not you declare it defaulted), so still obeys the "Rule of Zero". 您的类不需要声明析构函数(无论您是否声明默认实现,它都将获得正确的默认实现),因此仍然遵守“零规则”。
However, you might improve this by making the deleters function objects, rather than pointers: 但是,您可以通过使删除函数对象而不是指针来改进这一点:
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>>;
This has a few benefits: 这有一些好处:
unique_ptr
doesn't need to store an extra pointer unique_ptr
不需要存储额外的指针
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.