bar*_*ar3 6 c c++ pointers cross-language smart-pointers
我有一些处理对象创建和销毁的C API,它提供:createObject(...)和destroy(...).我想将它包装成一些更现代的构造/破坏机制,并将它们与智能指针一起使用.我担心在某些时候我会忘记破坏对象,否则会发生一些异常.
我知道自定义删除函数shared_ptr,但我无法显式调用new,因为createOjbect函数处理初始化.
在这种情况下我可以使用STL智能指针吗?从头开始,我是否必须在构造函数中实现初始化类,在析构函数中进行销毁以及在这种情况下引用计数?
该std::shared_ptr完全能够创建和删除与cutstom创造者和删除器对象,而是中new,你必须使用生成器功能.
我们考虑一下,我们有以下创建者和删除者:
typedef struct {
int m_int;
double m_double;
} Foo;
Foo* createObject(int i_val, double d_val) {
Foo* output = (Foo*)malloc(sizeof(Foo));
output->m_int = i_val;
output->m_double = d_val;
puts("Foo created.");
return output;
}
void destroy(Foo* obj) {
free(obj);
puts("Foo destroyed.");
}
Run Code Online (Sandbox Code Playgroud)
要管理Foo上述函数创建的实例,只需执行以下操作:
std::shared_ptr<Foo> foo(createObject(32, 3.14), destroy);
Run Code Online (Sandbox Code Playgroud)
std::shared_ptr如果您不希望共享对象的所有权,则使用该开销.在这种情况下,std::unique_ptr要好得多,但对于这种类型,您必须定义一个自定义删除函数,用它可以删除托管Foo实例:
struct FooDeleter {
void operator()(Foo* p) const {
destroy(p);
}
};
using FooWrapper = std::unique_ptr<Foo, FooDeleter>;
/* ... */
FooWrapper foo(createObject(32, 3.14));
Run Code Online (Sandbox Code Playgroud)
C++17。
template<auto X> using constant_t=std::integral_constant<std::decay_t<decltype(X)>, X>
template<auto X> constexpr constant_t<X> constant{};
template<class T, auto dtor> using smart_unique_ptr=std::unique_ptr< T, constant_t<dtor> >;
Run Code Online (Sandbox Code Playgroud)
现在假设您有一个Bob 用Bob* createBob(some_args...)and包装的 C API destroyBob(Bob*):
using unique_bob=smart_unique_ptr< Bob, destroyBob >;
unique_bob make_unique_bob(some_args args){
return unique_bob( createBob(args) );
}
Run Code Online (Sandbox Code Playgroud)
aunique_bob可以隐式移动到 a 中shared_ptr<Bob>。
一些额外的假设可以使这个在 C++14 中工作:
template<class T, void(*dtor)(T*)> using smart_unique_ptr=std::unique_ptr< T, std::integral_constant<decltype(dtor),dtor> >;
Run Code Online (Sandbox Code Playgroud)
假设 dtor 签名是void(T*).
在 C++11 中,您必须为零开销 unqiue ptr 编写一个新的无状态函数指针调度程序。