错误C2280 /在std :: vector中实例化对象时,复制构造函数出现问题?

问题描述 投票:0回答:2

我目前正在按照ChiliTomatoNoodle的教程对我的第一个应用程序进行编程,并根据我的需要修改他的代码。这样做并实现一个简单的WindowManager类(其目的是将所有窗口实例存储在std :: vector和类似的东西中)时,出现以下错误消息:

C:\ Program Files(x86)\ Microsoft Visual Studio \ 2019 \ Community \ VC \ Tools \ MSVC \ 14.23.28105 \ include \ xmemory(758,1):

错误C2280:'Window :: Window(const Window&)':试图引用已删除的函数(编译源文件src \ cpp \ WindowManager.cpp)

问题似乎出在addWindow函数中,该窗口实例化并存储在std::vector<Window> Wnd中:

void WindowManager::addWindow(unsigned short x, unsigned short y, unsigned short width, unsigned short height, const char* name, Window::WindowClass& windowClass, DWORD style) {

    this->Wnd.emplace_back(Window(name, x, y, width, height, windowClass, style, this->IdGenNum++));
}

我已经将push_back更改为emplace_back以避免复制(?),但并不能解决问题。

然后还有一个吸气剂(看起来很好,不复制任何东西):

Window& WindowManager::getWindow(const unsigned short id) {

    for (Window &element : this->Wnd) {

        if (element.Id == id) {

            return element;
        }
    }
}

这是Window类头:

class Window {

private:    // Friends

    friend class WindowManager;

public:     // Nested Classes

    class WindowClass {

        ...
    };

private:    // Variables and Instances

    unsigned short Id;    // Received by WindowManager on Creation

    const char* Name;

    HWND Handle;

    ...

public:     // Constructors and Deconstructors

    Window(const Window&) = delete;

    Window(

        const char* name,
        unsigned short x, 
        unsigned short y, 
        unsigned short width, 
        unsigned short height,  
        WindowClass& windowClass, 
        DWORD style,
        unsigned short id
    );

    ~Window();


private:    // Functions

    ...

public:     // Operators

    Window& operator=(const Window&) = delete;
};

编辑:

感谢所有答案和评论,指出必须将参数直接传递给emplace_back方法。事实证明,矢量仍然复制了对象(不知道为什么..),但是我可以改用std::list来解决此问题,它没有这种行为。

c++ windows window desktop-application window-managers
2个回答
0
投票
this->Wnd.emplace_back(Window(name, x, y, width, height, windowClass, style, this->IdGenNum++));

使用emplace_back,您无需创建临时文件,因为您提供给emplace_back的参数已完美地转发到了Window的构造函数,因此不会进行不必要的移动或复制:

this->Wnd.emplace_back(name, x, y, width, height, windowClass, style, this->IdGenNum++);

尽管这足以解决当前的问题,但是您的Window类看起来应该支持移动但不一定要复制。


1
投票
[您可以声明一个复制构造函数,使用push_back(),甚至更好地使用其他emplace_back()构造函数的参数来调用Window,这将避免复制。
© www.soinside.com 2019 - 2024. All rights reserved.