2010-12-08 11 views
14

기본적으로 임의의 창 핸들 (예 : HWND, HFONT)에 클래스를 연결하는 기본 클래스를 가지고 있으며 정책 클래스를 사용하여 첨부/분리 및 삭제합니다.이동 생성자 기본 클래스 이동 생성자

// class SmartHandle 
template<typename THANDLE, class TWRAPPER, class TPOLICY> 
class SmartHandle : boost::noncopyable 
{ 
private: 
    TPOLICY* m_pPolicy; // Policy 
    bool m_bIsTemporary; // Is this a temporary window? 

    SmartHandle(); // no default ctor 
    SmartHandle(const SmartHandle<THANDLE, TWRAPPER, TPOLICY>&); // no cctor 
protected: 
    THANDLE m_hHandle; // Handle to the underlying window 

    TPOLICY& policy() {return(*m_pPolicy);}; 

    // ctor that attaches but is temporary 
    SmartHandle(const THANDLE& _handle, bool _temporary) : m_hHandle(_handle) 
                 , m_bIsTemporary(_temporary) 
    { 
     m_pPolicy = new TPOLICY(reinterpret_cast<TWRAPPER&>(*this)); 
     if(_handle) 
      m_pPolicy->attach(_handle); 
    }; // eo ctor 

    // move ctor 
    SmartHandle(SmartHandle<THANDLE, TWRAPPER, TPOLICY>&& _rhs) : m_hHandle(_rhs.m_hHandle) 
                     , m_bIsTemporary(_rhs.m_bIsTemporary) 
    { 
     m_pPolicy = new TPOLICY(reinterpret_cast<TWRAPPER&>(*this)); 
     m_pPolicy->attach(m_hHandle); 
     const_cast<SmartHandle&>(_rhs).m_hHandle = NULL; 
    }; // eo mtor 

    // dtor 
    virtual ~SmartHandle() 
    { 
     if(m_hHandle) 
     { 
      m_pPolicy->detach(m_hHandle); 
      if(!m_bIsTemporary) 
       m_pPolicy->destroy(m_hHandle); 
      m_hHandle = NULL; 
     }; 
     delete(m_pPolicy); 
     m_pPolicy = NULL; 
    }; // eo dtor 

클래스를 복사하지 않으려 고 복사 생성자를 private (구현 없음)로 선언했지만, 이 허용됩니다.

Window 클래스는에서 파생 :

class GALLOW_API Window : SmartHandle<HWND, Window, detail::_hWndPolicy> 
    { 
    friend class Application; 
    private: 
     static LRESULT CALLBACK wndProc(HWND _hWnd, UINT _message, WPARAM _wParam, LPARAM _lParam); 

     // no copy/default ctor 
     Window(); 
     Window(const Window&); 
    protected: 

    public: 
     static const String ClassName; 
     Window(const HWND& _hWnd); 
     Window(const WindowCreateInfo& _createInfo); 
     Window(Window&& _rhs); 
     virtual ~Window(); 
    }; // eo class Window 

다시 한번, 복사 기본/복사 ctors을. 이동 생성자의 구현은 다음과 같습니다

Window::Window(Window&& _rhs) : SmartHandle(_rhs) 
    { 
    }; // eo mtor 

그러나, 컴파일시 I 이동 생성자 구현의 첫 번째 줄에 다음과 같은 오류 얻을 : 그것은 시도 것처럼 그래서

1>c:\\documents\visual studio 2010\projects\gallow\gallow\window.cpp(81): error C2248: 'gallow::SmartHandle<THANDLE,TWRAPPER,TPOLICY>::SmartHandle' : cannot access private member declared in class 'gallow::SmartHandle<THANDLE,TWRAPPER,TPOLICY>' 

, 그것은 나타납니다 이동 생성자보다는 복사 생성자 (private로 선언 한)를 호출해야합니다. 여기 내가 누락 된 간단한 것이 있습니까?

미리 감사드립니다.

EDIT : 수정되지 않은 mtor이므로 오류가 유지됩니다. EDIT2 : Visual C++ 2010을 사용하고 있습니다.

+2

중복? http://stackoverflow.com/questions/4086800/move-constructor-on-derived-object –

+0

에릭, 고마워, 나는 그것을 잡지 못했다. 그래, 그 문제를 완전히 해결, 내가 당신의 대답을 받아 들일 수 있으면 좋겠어 :) –

답변

4

이동 생성자는 T(const T&&)이 아니라 T(T&&)이어야합니다.

+0

고마워, 나는 이것을 고쳤지만 슬프게도 나는 받고있는 오류와 관련이 없다. –

10

명명 된 인수는 우 가치 참조로 처리되지 않으므로 move이어야합니다.

Window::Window(Window&& _rhs) : SmartHandle(std::move(_rhs)) 
{ 
} 

인수가를 rvalue로 간주되지 않습니다 그 이유는 두 번 사용하고 일반적으로 이동하는이 변수에서 이동 것을 알고에 대해 명시 적으로해야하므로 값을 변경 할 수 있다는 것입니다.

예컨대

void f(string&& first, string&& second) 
{ 
    string local = first; 
    cout << first; // I would be surprised if this is different from `local` 

    local = std::move(second); 
    // If I'm surprised after explicitly moving from second it's my problem 
} 

그것은)는 명확 이후 이동할와 b) 당신이 경향 자세한 오류입니다 forward에 대한 유형을 지정해야 할 때 경우에 move보다는 forward를 사용하는 것이 좋습니다.