我有一个C ++ RAII类,用于使用boost :: shared_ptr<>来管理Win32 HANDLE。看起来有点像这样:
namespace detail {
struct NoDelete { void operator()( void* ) {}; };
}; // namespace detail
template< typename HANDLE_TYPE, typename HANDLE_DELETER >
class CHandleT
{
public :
explicit CHandleT( HANDLE_TYPE handle, bool delete_on_release = true )
{
if( delete_on_release )
handle_ = Handle( handle, HANDLE_DELETER() );
else
handle_ = Handle( handle, detail::NoDelete() );
};
operator HANDLE_TYPE() const { return static_cast< HANDLE_TYPE >( handle_.get() ); };
protected:
typedef boost::shared_ptr< void > Handle;
Handle handle_;
}; // class CHandleT
struct DeallocateHandle
{
void operator()( void* handle ) { ::CloseHandle( handle ); };
};
typedef CHandleT< HANDLE, DeallocateHandle > CHandle;
我想扩展它,而不是写:
CHandle my_handle( ::CreateEvent( NULL, FALSE, FALSE, NULL ) );
::SetEvent( my_handle.get() );
我可以写:
CEvent my_event( NULL, FALSE, FALSE, NULL );
my_event.SetEvent();
最好的方法是使用CHandle类作为CEvent类的成员吗?
class CEvent
{
public:
explicit CEvent( LPSECURITY_ATTRIBUTES lpEventAttributes = NULL,
BOOL bManualReset = TRUE,
BOOL bInitialState = FALSE,
LPCTSTR lpName = NULL,
bool delete_on_release = true ) :
handle_( new CHandle( ::CreateEvent( lpEventAttributes,
bManualReset,
bInitialState,
lpName ),
delete_on_release ) )
{
};
BOOL SetEvent()
{
_ASSERT( NULL != handle_ && NULL != handle_.get() );
return ::SetEvent( handle_.get() );
};
private:
boost::shared_ptr< CHandle > handle_;
}; // class CEvent
或者,有更好的方法吗? (注意,我仍然希望维护由boost :: shared_ptr&lt;&gt;给出的CHandle的复制语义。
谢谢, PaulH
答案 0 :(得分:3)
我不会讨论boost :: shared_ptr或任何智能ptr。这里有几个原因,从线条之间的不同角度,以及为什么智能指针总是可以永远地被冗余或被打败。
代码似乎模拟了CLR和NT模型,在这种情况下,操作系统会为您正在执行的操作预定义语义。它被称为:: DuplicateHandle,它运行良好,更适合跨进程场景(并且会比boost :: interprocess或类似的更少)。它适用于其他一些情况。
现在是第二个,希望不是一个矛盾的位置,因为遏制焦点会逐渐胜出(但是当你为那些不断尖叫的人玩混音时,它与OO无关)包含我)。所以无论它多么罕见,或者它是否是OO,非OO或O(o)论证:“继承”在这里获胜。
为什么呢?因为它是一个可等待的句柄概念,包括Win32事件,Mutex,自动重置种类,Thread,除了critical_section之外的所有内容(它还有一个内部支持句柄 - 但在CLR和NT中都经过特殊处理,加上它有双重性质)。因此,它绝对有意义:
typedef CHandleT&lt;手柄&gt; WaitHandle的;
是“层次结构”的根,以及底层实现已经存在的复制语义。
最后,它最终会成为处理数据类型的最有效表示,因为它们将模仿您正在定位的操作系统,并且不需要引用计数或雪崩/波纹引用计数。
然后是跨平台开发和提升::线程并破坏了睡前故事: - )
答案 1 :(得分:2)
您不需要将句柄存储在CEvent中作为shared_ptr。句柄已通过CHandleT属性共享。
只要您不想将CEvent元素用作CHandleT元素(使用多态),组合就可以了。