2010-12-08 20 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 

コピーコンストラクタをプライベート(実装なし)と宣言しましたが、クラスをコピーしないようにしましたが、移動です。

マイ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>' 

は、それが表示されます移動コンストラクタではなくコピーコンストラクタ(プライベート宣言した)を呼び出すことができます。私はここで欠けている簡単なものがありますか?

ありがとうございます。

EDIT:修正されたmtorで非constなので、エラーが残ります。 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)) 
{ 
} 

引数は右辺値として扱われていない理由は、それが2回使用し、一般的に移動するあなたは、この変数はから移動していることを知っについて明示する必要がため、値を変更することができるということです。

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 
} 

これは、a)は、それが明確なので、移動したいと、b)あなたがしやすい冗長で誤りであるforwardのための型を指定する必要がある場合のケースでmoveではなくforwardを使用することをお勧めします。