You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用嵌套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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:33:32