我正在编写一个使用两个使用C接口(interface)创建的对象的类。对象看起来像:
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
可复制,但我不希望这样。使用
MyClass
语义并仍然遵守零规则的正确方式写unique_ptr
是什么? 最佳答案
您的类无需声明析构函数(无论您是否声明为默认值,它都将获得正确的默认实现),因此仍应遵循“零规则”。
但是,您可以通过使deleters函数成为对象而不是指针来改善此问题:
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
不需要存储额外的指针关于c++ - unique_ptr,自定义删除器和零规则,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29035711/