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

发布于 2024-10-06 16:04:58 字数 3009 浏览 8 评论 0原文

我有一个基类,它基本上将一个类附加到任意窗口句柄(例如,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,使其成为非常量,错误仍然存​​在。 EDIT2:我正在使用 Visual C++ 2010。

I have a base class that basically wraps up attaching a class to a arbitrary windows handle (e.g, HWND, HFONT), and uses a policy class to attach/detach and destroy:

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

Note that I've declared the copy constructor private (with no implementation) as I do not want the class to be copied, but a move is allowed.

My Window class derives from this:

    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

Once again, copy default/copy ctors. The implementation of the move constructor is:

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

However, during compilation I get the following error on the first line of the move constructor implementation:

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

So, it appears as if it is trying to call the copy constructor (which I've declared private) rather than the move constructor. Is there something simple I am missing here?

Thanks in advance.

EDIT: Modified mtor so it was non-const, error remains.
EDIT2: I am using Visual C++ 2010.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

愁以何悠 2024-10-13 16:04:58

其实应该是这样的。

Window::Window(Window&& _rhs) : SmartHandle( std::forward<SmartHandle>( _rhs ) )     {     };  // eo mtor 

http://msdn.microsoft.com/en-us/library/ee390914.aspx

actually it should be like this.

Window::Window(Window&& _rhs) : SmartHandle( std::forward<SmartHandle>( _rhs ) )     {     };  // eo mtor 

http://msdn.microsoft.com/en-us/library/ee390914.aspx

白况 2024-10-13 16:04:58

命名参数不被视为右值引用,您必须移动它。

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,因为 a) 更清晰,b) 您需要为 forward< 指定类型/code> 这是冗长且容易出错的。

A named argument isn't treated as a rvalue reference you have to move it.

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

The reason an argument isn't treated as an rvalue is that it can be used twice and moving typically changes the value therefore you have to be explicit about knowing that this variable is moved from.

e.g.

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
}

It's better to use move rather than forward in cases when you want to move since a) it's clearer and b) you need to specify a type for forward which is verbose and error prone.

孤独陪着我 2024-10-13 16:04:58

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

A move constructor should be T(T&&), not T(const T&&).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文