2010-12-08 203 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这是冗长且容易出错。