C++ 和 Windows 正在互相争斗,我需要让他们停止。
我有一个 Visual Studio 2022 生成的类,它实现了
CDialogEx
,我需要将其添加到能够插入的数组中。这很难。
Visual Studio 2022 为对话框生成的类如下所示:
class SignPage : public CDialogEx
{
DECLARE_DYNAMIC(SignPage)
public:
SignPage(CWnd* pParent = nullptr); // standard constructor
virtual ~SignPage();
// Dialog Data
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_SIGN_PAGE };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
DECLARE_MESSAGE_MAP()
};
Visual Studio 生成的类的实现如下所示:
// SignPage.cpp : implementation file
//
#include "pch.h"
#include "App.h"
#include "afxdialogex.h"
#include "SignPage.h"
// SignPage dialog
IMPLEMENT_DYNAMIC(SignPage, CDialogEx)
SignPage::SignPage(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_SIGN_PAGE, pParent)
{
}
SignPage::~SignPage()
{
}
void SignPage::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(SignPage, CDialogEx)
END_MESSAGE_MAP()
// SignPage message handlers
我知道能够插入的数组是
std::vector
,但是将任何Windows生成的对象插入std::vector
会导致“尝试引用已删除的函数”错误,因为Windows已删除其对象中的复制和移动函数。
我不希望能够插入的数组以任何方式干扰 Windows 提供的对象,因此我理解
std:unique_ptr
是我所需要的,以便我将指向 Windows 提供的对象的指针添加到列表中。
我像这样实例化对象和向量,编译器喜欢它:
std::vector<std::unique_ptr<SignPage>> m_dlgs;
std::unique_ptr<SignPage> upm_dlg1 = std::make_unique<SignPage>();
现在我尝试将
upm_dlg1
插入到 m_dlgs 中,如下所示:
std::vector<std::unique_ptr<SignPage>>::iterator it;
it = m_dlgs.begin();
m_dlgs.insert(it, upm_dlg1); <---- error happens here
添加上面最后一行会导致模板内出现编译错误,呈现唯一指针,如下所示:
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.40.33807\include\xmemory(700,82): error C2280: 'std::unique_ptr<SignPage,std::default_delete<SignPage>>::unique_ptr(const std::unique_ptr<SignPage,std::default_delete<SignPage>> &)': attempting to reference a deleted function
有谁知道我必须采取什么步骤来解决这个问题?
我的局限性是:
我需要添加到能够插入的数组中的对象是由 Visual Studio 生成的,以便 Windows 受益。我修改这些对象的选择是有限的。
编译器错误是在我理解的实现
unique_ptr
的模板深处触发的。我假设这就是 C++ 编译器错误的乐趣。
我被引导相信
std::vector
是我应该使用的集合,但事实可能并非如此,有人可以证实吗?我不需要排序或任何其他复杂性,只是一个简单的数组,我可以在其中插入和删除,而无需以任何方式接触列表中的对象。
这一行:
m_dlgs.insert(it, upm_dlg1);
尝试在 upm_dlg1
内创建
std::vector
的 副本。
std::unique_ptr
,因此无法复制:std::unique_ptr
的复制构造函数是deleted,这就是错误“尝试引用已删除的函数”的原因。
相反,您应该按以下方式使用 std::vector
到
std::move
中:
//----------------vvvvvvvvv------------
m_dlgs.insert(it, std::move(upm_dlg1));
std::move
并没有真正移动任何东西:
std::move 用于指示对象 t 可以“移出”, 即允许资源从 t 有效转移到另一个 对象。
实际上,这是通过转换为 R 值引用来完成的。
然而,最终结果正是您所需要的,因为它将使用
std::vector::insert
的适当重载来触发,执行移动而不是复制。