2009-11-09 5 views
0

내가 Win32에서 관리를위한 C++ RAII 클래스가에 기능을 추가 :: shared_ptr의 <> 보이는이 같은 비트 :부스트를 사용하여 처리하는 핸들 래퍼

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(); 

이 가장 좋은 방법은 그 일 할 것인가 t 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 

또는 더 좋은 방법이 있습니까? (난 아직도 부스트에 의해 주어진 CHandle의 복사 의미를 유지하고자합니다 :: shared_ptr을 <>.

감사합니다, PaulH

내가 부스트 :: shared_ptr의 또는 스마트에 대한 논의로받지 않습니다

답변

3

ptr. 그리고 각기 다른 각도에서, 왜 똑똑한 포인터가 언제나 그리고 언제나 중복되고 구타 될 수있는 몇 가지 이유가 있습니다.

코드가 CLR과 NT 모델을 에뮬레이트하는 것처럼 보입니다. 당신이하고있는 것을 OS가 미리 정의한 시맨틱 스입니다 :: DuplicateHandle이라고 불리우며 잘 작동하며 교차 프로세스 시나리오에 더 적합합니다 (그리고 부울보다 덜 해킹 할 것입니다 st :: interprocess 또는 유사). 그리고 그것은 다른 몇몇 상황에 적용 가능합니다.

이제 두 번째로, 가난한 늙은 세상의 유산이 퇴보하는 곳에서 contraversial 비트가 아니 었습니다. 왜냐하면 봉쇄 포커스가 regurarly로 이기기 때문입니다. (그래도 계속 소리 지르는 사람들을 위해 믹스 인을 할 때 실제로 OO와는 아무런 관련이 없습니다. : 나를 포함해라). 아무리 희소해도 OO가 아닌 OO 또는 O (o) 인수는 "상속"입니다.

왜? 이는 Win32 이벤트, 뮤텍스 (Mutex), 자동 리셋 종류, 스레드, critical_section (내부의 깊숙한 핸들이 있지만 - 특별히 CLR과 NT 모두에서 처리되는 것)과는 별도로 모든 것을 기다리는 핸들 개념이기 때문에 이중 성질). 따라서 절대적인 의미를 갖습니다 :

typedef CHandleT < 핸들> WaitHandle;

은 기본 구현이 이미 무엇인지에 대한 복사 의미와 함께 "계층 구조"의 루트가되어야합니다.

마지막으로, 목표로하는 OS를 모방하고 참조 횟수 나 눈사태/파문 심판 횟수를 필요로하지 않으므로 핸들 인 데이터 유형을 가장 효율적으로 표현합니다.

그런 다음 크로스 플랫폼 개발을 와서 부스트 : 스레드 ING와 당신은있는 shared_ptr로 CEvent에서 핸들을 저장할 필요가 없습니다

+0

+1 DuplicateHandle의 경우 –

+2

@ Majk-a-Ra, 상속이 왜 우승합니까? CHandleT를 "scoped_handle"로 사용하고 다형성이 필요하지 않은 경우. 적은 커플 링 옵션이 승자가되어야합니다. –

+0

그것은 인용되었고 당신은 맞는 키워드를 제공합니다 : 구성. 반면 믹스 인은 커플 링이 아닙니다. 중앙에서 핸들 유형을 바꿀 수 있으며 더 많이 할 수 있습니다. 헤더와 템플리트가 커플 링하지 않는 것과 같습니다. 그들의 .cpp를 좋아하는 사람들은 보통 너무 사랑한다. :) Composition-based 기술은 거기에서 가장 과소 평가 된 것 중 하나이지만 기능적인 공간에서는 문제가되지 않는다. OO 사람들은 그 이상에 대해 질문 할 필요가 있습니다. 이유는 없습니다. 알고리즘에서도 확실하지만 어느 것도 유용하지는 않지만 구성은 상속이나 포함하지 않고 다형성을 다루지 않는 기능적 형태로 두드러집니다 .. –

2

:-) 침대 시간 이야기를 망 쳤어. 핸들은 이미 CHandleT 특성을 통해 공유됩니다.

당신은 (다형성을 사용하여) CHandleT 요소로 CEvent 요소를 사용하고 싶지 않은 한 구성 할 수 있습니다.