使用boost :: shared_ptr<>处理管理

时间:2010-08-11 15:51:10

标签: c++ boost shared-ptr

我想使用boost :: shared_ptr<>封装句柄的生命周期管理。我的句柄和它的创建/销毁函数声明如下:

typedef const struct MYHANDLE__ FAR* MYHANDLE;

void CloseMyHandle( MYHANDLE );
MYHANDLE CreateMyHandle();

理想情况下,我想像这样使用boost::shared_ptr<>来管理句柄:

boost::shared_ptr< void > my_handle( CreateMyHandle(), &CloseMyHandle );

不幸的是,因为句柄被声明为const struct *而不是通常的void *,所以我得到这样的错误:

boost/smart_ptr/shared_ptr.hpp(199) : error C2440: 'initializing' : cannot convert from 'const MYHANDLE__ *' to 'void *'

我可以使用仿函数将void *投射到这样的MYHANDLE

struct DeallocateMyHandle
{ 
    void operator()( void* handle )
    {
        CloseMyHandle( ( MYHANDLE )handle ); 
    };
};

boost::shared_ptr< void > my_handle( ( void* )CreateMyHandle(), DeallocateMyHandle() );

但是,我宁愿有一个不涉及单独的仿函数的方法。有没有办法在我看不到的boost::shared_ptr<>构造函数中执行此操作?或者,我是否坚持使用仿函数?

谢谢, PaulH

3 个答案:

答案 0 :(得分:4)

为什么不使用:

boost::shared_ptr< const MYHANDLE__ > my_handle( CreateMyHandle(), &CloseMyHandle );

PS。请注意,不允许使用双下划线(它是为实现保留的) 请参阅:Rules about identifers

答案 1 :(得分:2)

如果HANDLE是一个公共类型,但它所指的类型不是,那么写一个非常简单的方法:

template <typename T> struct unpointer { };
template <typename T> struct unpointer<T*> { typedef T type; };
boost::shared_ptr<typename unpointer<MYHANDLE>::type> my_handle(
  CreateMyHandle(), &CloseMyHandle);

(如果您使用的是旧版本的VC ++或gcc,则可能需要省略“typename”。)

当然这有点冗长乏味。如果你只有一个句柄类型可以处理,你可能会这样写:

typedef typename unpointer<MYHANDLE>::type MYHANDLEREF;
typedef boost::shared_ptr<MYHANDLEREF> my_shared_ptr;

如果你有各种各样的句柄来包装(并且因为它看起来你正在做Win32 API的事情,你可能会这样做),创建一个模板,在你喜欢的任何级别包装东西(一个类模板,只需生成类型,handle_ptr<T>子类shared_ptr<unpointer<T>>并为您添加默认值,handle_ref<T>在幕后使用shared_ptr假冒{{1}而不是伪造成MYHANDLE &是指针等等。)

答案 2 :(得分:0)

您的shared_ptr类型必须是这样的:

boost::shared_ptr< const MYHANDLE__ FAR>

shared_ptr指出一个指针时,它变为:

const MYHANDLE__ FAR*

与您的MYHANDLE类型完全匹配:

#include <boost/shared_ptr.hpp>

struct MYHANDLE__ {};
typedef const MYHANDLE__* MYHANDLE;

void CloseMyHandle(MYHANDLE) {}
MYHANDLE CreateMyHandle(void) { return 0; }

int main()
{
    typedef boost::shared_ptr<const MYHANDLE__> ptr_type;
    ptr_type my_handle( CreateMyHandle(), &CloseMyHandle );
}

注意,我确实怀疑你需要FAR,这是16位年龄。它会扩展为far或者没有任何内容,具体取决于您是否正在编译16位(提示:您没有编译为16位。:))。据我所知,far甚至不再是延伸。

另外,就像马丁所说的那样,不要在任何地方使用双下划线。