我目前正在按照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
来解决此问题,它没有这种行为。
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
类看起来应该支持移动但不一定要复制。
push_back()
,甚至更好地使用其他emplace_back()
构造函数的参数来调用Window
,这将避免复制。