使用嵌套CArray的CMap时触发C2248私有成员访问错误的技术咨询
解决MFC CMap存储CArray时的error C2248问题
这个错误的核心原因很明确:CArray是CObject的派生类,而CObject的拷贝构造函数是私有的。当你调用m_mUserNameMap->SetAt(1, sUName)时,CMap会尝试复制传入的CArray对象,但因为CArray没有公开的拷贝构造函数(继承自CObject的限制),编译器就会抛出这个访问权限错误。
另外先纠正你代码里的一个小错误:sUName.id = 10;是不对的,sUName是CArray<USER_NAME>类型,不是单个USER_NAME对象,你需要先创建USER_NAME实例,再添加到数组中。
下面给你两种可行的解决方案:
方案一:改用std::vector替代CArray
std容器(比如std::vector)支持正常的拷贝操作,完全可以作为CMap的值类型使用,代码调整如下:
// 头文件中定义 typedef struct { int id; CString name; } USER_NAME; CMap<int,int, std::vector<USER_NAME>, std::vector<USER_NAME>> * m_mUserNameMap; // CPP文件中实现 std::vector<USER_NAME> sUName; USER_NAME user; user.id = 10; user.name = _T("Test it!!!"); sUName.push_back(user); m_mUserNameMap = new CMap<int,int, std::vector<USER_NAME>, std::vector<USER_NAME>>; m_mUserNameMap->SetAt(1, sUName);
这种方法不需要额外管理指针内存,std::vector的拷贝行为是安全的,而且USER_NAME里的CString本身也是可拷贝的,不会有问题。
方案二:将CArray作为指针存储在CMap中
如果你一定要使用MFC的CArray,可以把CMap的值类型改成CArray<USER_NAME>*(指针类型),这样CMap存储的是指针,不需要拷贝CArray对象,自然就避开了拷贝构造的问题:
// 头文件中定义 typedef struct { int id; CString name; } USER_NAME; CMap<int,int, CArray<USER_NAME>*, CArray<USER_NAME>*> * m_mUserNameMap; // CPP文件中实现 CArray<USER_NAME>* sUName = new CArray<USER_NAME>; USER_NAME user; user.id = 10; user.name = _T("Test it!!!"); sUName->Add(user); m_mUserNameMap = new CMap<int,int, CArray<USER_NAME>*, CArray<USER_NAME>*>; m_mUserNameMap->SetAt(1, sUName);
⚠️ 注意:这种方法需要手动管理内存,当你不再需要这个CMap时,需要遍历CMap中的每个元素,删除对应的CArray指针,然后再删除CMap本身,避免内存泄漏。比如:
POSITION pos = m_mUserNameMap->GetStartPosition(); int key; CArray<USER_NAME>* val; while (pos != nullptr) { m_mUserNameMap->GetNextAssoc(pos, key, val); delete val; } delete m_mUserNameMap; m_mUserNameMap = nullptr;
内容的提问来源于stack exchange,提问作者donguy76
相关产品推荐
相关产品推荐

