2010-12-08 204 views
14

我有一個基類,基本上將類附加到任意窗口句柄(例如,HWND,HFONT),並使用策略類來附加/分離和銷燬:Move構造函數調用基類移動構造函數

// 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 

請注意,我已經聲明覆制構造函數是私有的(沒有實現),因爲我不希望該類被複制,但移動是允許的

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 

再次複印默認/複印構建函數。此舉構造函數的實現是:

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

然而,在編譯過程中,我得到的移動構造函數執行的第一線以下錯誤:

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)而不是移動構造函數。有沒有簡單的我在這裏失蹤?

在此先感謝。

編輯:修改mtor所以它是非常量,錯誤仍然存​​在。 EDIT2:我正在使用Visual C++ 2010.

+2

複製? http://stackoverflow.com/questions/4086800/move-constructor-on-derived-object – 2010-12-08 18:54:04

+0

埃裏克,謝謝,我沒有明白。是的,這完全解決了這個問題,希望我能接受你的答案:) – 2010-12-08 18:56:18

回答

4

移動構造函數應該是T(T&&)而不是T(const T&&)

10

一個命名的參數不被視爲右值引用,你必須move它。

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

參數沒有作爲右值處理的原因是,它可以被使用兩次,並且因此典型地移動改變所述值你必須明確的關於知道這個變量是從移動。

例如

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 
} 

這是更好地使用move,而不是forward的情況下,當你想要移動因爲)它更清晰和b)你需要指定一個類型forward這是冗長且容易出錯。