2010-12-08 19 views
14

Tengo una clase base que básicamente termina asociando una clase a un manejador de ventanas arbitrario (por ejemplo, HWND, HFONT) y usa una clase de política para adjuntar/separar y destruir:Move Constructor llamando a la clase base Move Constructor

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

Tenga en cuenta que he declarado el constructor de copia privada (sin aplicación), ya que no quiero la clase que va a copiar, pero un movimiento se admiten.

Mi clase Window deriva de esto:

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 Una vez más, por defecto copia/copia. La aplicación de la medida constructor es:

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

Sin embargo, durante la compilación me sale el siguiente error en la primera línea de la aplicación movimiento constructor:

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

lo tanto, parece como si se está tratando llamar al constructor de copia (que he declarado privado) en lugar del constructor de movimientos. ¿Hay algo simple que me falta aquí?

Gracias de antemano.

EDITAR: Modificado mtor por lo que no fue const, el error permanece. EDIT2: Estoy usando Visual C++ 2010.

+2

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

+0

Eric, gracias, no entendí eso. Sí, eso resolvió el problema por completo, desearía poder aceptar tu respuesta :) –

Respuesta

4

Un constructor de movimiento debe ser T(T&&), no T(const T&&).

+0

Gracias, modifiqué esto, pero desafortunadamente no está relacionado con el error que estoy recibiendo. –

10

Un argumento con nombre no se trata como una referencia de valor r que tiene que move.

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

La razón un argumento no es tratado como un valor p es que puede ser usado dos veces y se mueve normalmente cambia el valor por lo tanto, usted tiene que ser explícito acerca sabiendo que esta variable se mueve desde.

p. Ej.

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 
} 

Es mejor utilizar move en lugar de forward en los casos en que desea mover ya que a) es más clara y b) es necesario especificar un tipo de forward que es prolijo y propenso a errores.

Cuestiones relacionadas