含CList的结构体用于CMap编译报C2280错误的解决咨询
解决CMap存储含CList的结构体编译错误
错误原因
MFC的CList类没有默认可访问的拷贝构造函数,编译器自动为RECIPENODE生成的拷贝构造函数因包含CList被标记为删除状态,而CMap在插入、查找元素时需要调用结构体的拷贝构造函数,因此触发C2280错误。
优先保留CList的解决方法
方法1:手动实现结构体的拷贝构造与赋值运算符
给RECIPENODE添加自定义的拷贝构造函数和赋值运算符,利用CList的CopyList方法完成列表内容的深拷贝:
struct RECIPENODE { CString name; CList<CString> children; // 拷贝构造函数 RECIPENODE(const RECIPENODE& other) : name(other.name) { children.CopyList(&other.children); } // 赋值运算符重载 RECIPENODE& operator=(const RECIPENODE& other) { if (this != &other) { name = other.name; children.RemoveAll(); children.CopyList(&other.children); } return *this; } }; typedef CMap<CString, LPCTSTR, RECIPENODE, RECIPENODE> CRecipeNodeMap; CRecipeNodeMap nodeMap;
方法2:将结构体指针存入CMap
让CMap存储RECIPENODE的指针,避免直接拷贝结构体对象。注意使用完成后要手动释放内存防止泄漏:
struct RECIPENODE { CString name; CList<CString> children; }; typedef CMap<CString, LPCTSTR, RECIPENODE*, RECIPENODE*> CRecipeNodeMap; CRecipeNodeMap nodeMap; // 插入示例 RECIPENODE* pNode = new RECIPENODE; pNode->name = _T("Test"); pNode->children.AddTail(_T("Child1")); nodeMap.SetAt(_T("Key1"), pNode); // 释放内存示例 POSITION pos = nodeMap.GetStartPosition(); while (pos != nullptr) { CString key; RECIPENODE* pDelNode; nodeMap.GetNextAssoc(pos, key, pDelNode); delete pDelNode; } nodeMap.RemoveAll();
改用std::vector的方案
如果上述方法不符合需求,将CList替换为std::vector<CString>,因为std::vector支持默认的深拷贝,编译器会自动生成合法的结构体拷贝构造函数,无需额外代码:
#include <vector> struct RECIPENODE { CString name; std::vector<CString> children; }; typedef CMap<CString, LPCTSTR, RECIPENODE, RECIPENODE> CRecipeNodeMap; CRecipeNodeMap nodeMap;
内容的提问来源于stack exchange,提问作者APA
相关产品推荐
相关产品推荐

