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

VS2019 C++报错C2280:尝试引用CBrush已删除函数如何排查

问题根因

C2280报错的本质是你调用了被显式删除的拷贝构造函数。你使用的CBrush是MFC的GDI对象类,这类资源持有类的拷贝构造、拷贝赋值运算符默认被MFC框架删除——因为GDI对象是Windows内核资源,随意拷贝会导致资源泄漏、重复释放等问题。
你写的static CBrush BrushList[] = { CBrush(ClrList[0]), ... }初始化代码,在旧版本C++标准下,语法层面要求数组初始化必须调用拷贝构造函数,把临时CBrush对象拷贝到数组内存中,哪怕编译器会做复制消除,也要求拷贝构造函数必须存在且可访问,因此触发了报错。

可行解决方案

  • 方案1:改用指针数组存储CBrush实例
    把数组定义改为CBrush*类型,每个元素动态构造,避免拷贝操作:
static CBrush* BrushList[] = { new CBrush(ClrList[0]),
                                new CBrush(ClrList[1]),
                                new CBrush(ClrList[2]),
                                new CBrush(ClrList[3]),
                                new CBrush(ClrList[4]),
                                new CBrush(ClrList[5]),
                                new CBrush(ClrList[6]),
                                new CBrush(ClrList[7]) };

后续使用时直接通过指针访问即可,程序退出前记得手动delete每个元素释放资源,避免GDI资源泄漏。

  • 方案2:延迟初始化,先声明空数组再逐个初始化
    CBrush提供了默认构造函数,你可以先定义空的CBrush数组,再调用CreateSolidBrush接口逐个初始化:
static CBrush BrushList[8];
// 初始化代码放在项目的初始化逻辑位置(比如窗口初始化函数内)
for (int i = 0; i < 8; i++) {
    BrushList[i].CreateSolidBrush(ClrList[i]);
}

该方案不需要手动释放资源,CBrush析构时会自动释放持有的GDI句柄。

  • 方案3:升级编译标准到C17及以上
    C
    17引入了强制复制消除规则,这种纯右值初始化数组的场景不需要拷贝构造函数存在,会直接在数组内存上构造对象。你可以在项目属性的「C/C++ -> 语言 -> C++语言标准」中选择ISO C++17 标准 (/std:c++17)或更高版本,重新编译即可通过。

内容的提问来源于stack exchange,提问作者Max Morgunov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 06:15:02