0

まず、クラス インスタンスをスコープ内からスコープ外に移動しようとしています。正しい用語を使用しているかどうかはわかりませんが、次のようになります。

Button Btn;  //Declare blank object out of scope..

LRESULT __stdcall WindowProcedure(/*Params here*/)
{
    switch(message)
    {
        case WM_CREATE:
        {
            Btn = std::move(Button("Title", Point(0, 0), 95, 22, hwnd)); //Move assign the scoped object..
        }
        break;

        case WM_COMMAND:
            Btn.SetText("New Title"); //Access the Non-Scoped button to see if the Move really worked.
        break;
    }

    return 0;
}

したがって、上記のように、スコープ オブジェクトをムーブ割り当てを使用してスコープ外に移動しようとしました。そのため、スコープ オブジェクトがその内容を非スコープ オブジェクトに割り当ててから、スコープ オブジェクトを破棄することを期待しています。

ただし、WM_COMMAND を受信するとエラーがスローされるため、何か問題があることがわかります。しかし、何が悪いのかわかりません。私の Bitmap クラス (継承なし) で同じ/類似の手法を実行すると、うまくいきます。

私のコードは次のとおりです。

class Control
{
    private:
        HMENU ID;
        HWND Handle, Parent;
        std::string Class, Title;
        void Swap(Control &C);

    public:
        Control(const Control &C) = delete; //Copying is not allowed.
        Control(Control &&C);               //Moving is allowed.
        Control(DWORD dwExStyle, /*Other params here*/);
        Control(DWORD dwExStyle, /*More params here*/);
        virtual ~Control();

        virtual void Dispose();

        Control& operator = (const Control &C) = delete; //Copying through assignment not allowed.
        Control& operator = (Control&& C);               //Move through assignment allowed.

    protected:
        Control();
        bool Initialized;
        static LRESULT __stdcall SubClass(HWND Window, UINT Msg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
};

class Button : public Control
{
    public:
        Button();
        Button(const Button &B);  //Copying is allowed.
        Button(Button&& B);       //Moving is allowed.
        Button(std::string Title, Point Location, /*Other params here*/);
        Button(std::string Title, DWORD dwStyle, /*More params here*/);
        virtual ~Button();

        virtual void Dispose() override;

        Button& operator = (const Button &B) = delete; //Copy through assignment not allowed. (cannot be overriden)
        Button& operator = (Button&& B);      //Move through assignment allowed. Non-virtual (cannot be overriden)
};




Control::~Control() {}

void Control::Swap(Control &C)
{
    using std::swap;
    swap(ID, C.ID);
    swap(Handle, C.Handle);
    swap(Parent, C.Parent);
    //Swap all members..
}

/*All other constructors here..*/

Control::Control(Control &&C) : ID(std::move(C.ID)), Handle(std::move(C.Handle)), /*move all member*/ {}

void Control::Dispose()
{
    ID = nullptr;
    Parent = nullptr;

    if (Handle != nullptr)
    {
        DestroyWindow(Handle);
        Handle = nullptr;
    }
}

Control& Control::operator = (Control&& C)
{
    if (this->Handle != C.Handle)
    {
        /*this->ID = std::move(C.ID);
        this->Handle = std::move(C.Handle);
        this->Parent = std::move(C.Parent);
        this->Class = std::move(C.Class);
        this->Title = std::move(C.Title);
        this->dwExStyle = std::move(C.dwExStyle);
        this->dwStyle = std::move(C.dwStyle);
        this->Location = std::move(C.Location);
        this->Width = std::move(C.Width);
        this->Height = std::move(C.Height);*/
        C.Swap(*this);      //Do I use my swap func? Or do I use std::move?
        C.Dispose();
    }
    return *this;
}

//Button constructors are the same as the Control constructors with the initialization stuff.. just different parameters.

Button::Button(const Button &B) : Control(B.ID + 1, B.Class, B.Title, /*all other params */) {} //Copy constructor..

Button& Button::operator = (Button&& B)
{
    Control::operator = (std::move(B)); //I believe it is this line that probably throws.
    return *this;
}
4

1 に答える 1

1

コントロールの内容を移動し、元に戻し、コントロールとボタンの両方を破棄します。

これにより、Control を適切に移動できないだけでなく、他の Button も無効になります。

動作するムーブ コンストラクタを記述します。割り当て移動には、移動スワップ イディオムを使用します。move ctor と swap の両方が正しく記述されていれば、これは機能します。

于 2013-03-09T19:55:52.410 に答える