2010-12-08 30 views
14

Temel olarak bir sınıfın rasgele bir windows tanıtıcısına (örn. HWND, HFONT) eklenmesini sağlayan bir temel sınıfım var ve iliştirmek/çıkarmak ve yok etmek için bir ilke sınıfı kullanıyor:Move Constructor çağrılıyor taban sınıfı 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 

sınıf kopyalanamaz istemiyorum gibi (hiçbir uygulamasıyla) kopya yapıcı olarak gizli ilan ettik Not ama izin verilen bir hareket.

Benim Window sınıf bu kaynaklanmaktadır:

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 

kez daha, kopya varsayılan/kopyala vektörlerin içine klonlanabilir. Hareket yapıcı uygulanmasıdır:

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

Ancak, derleme sırasında ben hareket yapıcı uygulamasının ilk satırında aşağıdaki hata alıyorum: o çalışıyor sanki Yani

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

, göründüğü Taşımacı yerine, özel olarak bildirdiğim kopya kurucuyu çağırmak. Burada eksik bir şey var mı?

Şimdiden teşekkürler.

DÜZENLEME: Modifiye edilmiş mtor bu yüzden const değil, hata kalır. EDIT2: Visual C++ 2010 kullanıyorum.

+2

çoğaltın? http://stackoverflow.com/questions/4086800/move-constructor-on-derived-object –

+0

Eric, teşekkürler, onu yakalamadım. Evet, bu sorunu tamamen çözdüm, cevabını kabul edebilseydim :) –

cevap

4

Bir taşıma kurucusu T(const T&&) değil T(T&&) olmalıdır.

+0

Teşekkürler, bunu değiştirdim ama aldığım hatayla ilgisi yok. –

10

Adlandırılmış bir argüman, move'a sahip olduğunuz bir rvalue referansı olarak değerlendirilmez.

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

Bağımsız değişken bir rvalue olarak tedavi edilmezse nedeni iki kez kullanılır ve tipik hareketli bu değişken taşınır bilerek konusunda açık olmak zorunda bu nedenle değerini değiştirir edilebilir olmasıdır.

örn.

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 
} 

O a) net olduğundan taşımak istediğiniz ve b) eğilimli ayrıntılı ve hatadır forward için türünü belirtmek için gerektiğinde durumlarda move yerine forward kullanmak daha iyidir.

İlgili konular