移动构造函数调用基类的移动构造函数

15

我有一个基类,基本上将一个类附加到任意窗口句柄(例如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

再次复制默认/复制构造函数。移动构造函数的实现如下:

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

所以,似乎它正在尝试调用拷贝构造函数(我已将其声明为私有),而不是移动构造函数。我错过了什么简单的东西吗?

提前感谢。

编辑:修改了mtor使其非const,错误仍然存在。 编辑2:我正在使用Visual C++ 2010。


2
重复的问题?https://dev59.com/bG855IYBdhLWcg3w6IvV - Éric Malenfant
Eric,谢谢,我没听清楚。是的,那完全解决了问题,但愿我能接受你的答案 :) - Moo-Juice
3个回答

13

11

命名参数不会被视为右值引用,你需要对其进行move操作。

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

参数不被视为rvalue的原因是它可以被使用两次,而移动通常会改变值,因此您必须明确知道该变量已被移动。

例如:

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,因为a)更清晰,b)你需要为forward指定一种类型,这很啰嗦且容易出错。


5
移动构造函数应该是T(T&&),而不是T(const T&&)

谢谢,我已经修改了,但是很遗憾它与我收到的错误无关。 - Moo-Juice

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接