提问人:Barry 提问时间:3/13/2015 最后编辑:Barry 更新时间:3/14/2015 访问量:615
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* );
(类似于 )。因为 C++11,我想把它们包装在一个智能指针中,这样我就不必编写任何特殊方法。该类将对这两个对象具有唯一的所有权,因此从逻辑上讲是有道理的......但我仍然需要编写一个构造函数:bar_t
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
答:
9赞
Mike Seymour
3/13/2015
#1
你的类不需要声明析构函数(无论你是否声明它默认,它都会得到正确的默认实现),所以仍然遵循“零规则”。
但是,您可以通过使删除程序函数对象而不是指针来改进这一点:
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
- 可以直接调用 Delete 函数,而不是通过指针调用
- 你不需要编写构造函数;默认构造函数将执行正确的操作。
评论
0赞
rubenvb
3/14/2015
这看起来像应该在标准库中的东西。
1赞
Barry
3/14/2015
这太棒了。我最终做了一个轻微的变化,它有一个私人类,然后.节省了必要的打字量...然后我可以把两者粘在一起(template <typename T, void (*Deleter)(T*)> struct unique_ptr_deleter;
deleter
using type = std::unique_ptr<T, deleter>;
unique_ptr_deleter_t<foo_t, delete_foo> foo_;
)
上一个:了解零法则
评论