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

C++ C2280错误:向vector添加Brick对象时引用已删除函数的排查与解决

C2280错误原因及修复方案

错误原因

std::vector::push_back向容器添加元素时,会调用元素类型的拷贝构造函数完成对象复制。你的Brick类包含XMLDocument类型成员mDoc,而TinyXML的XMLDocument类没有提供可访问的拷贝构造函数(或明确禁用了拷贝操作)。根据C++规则,当类包含无法拷贝的成员时,编译器会自动删除该类的拷贝构造函数与拷贝赋值运算符。执行brickArr.push_back(brick)时,尝试调用已被删除的Brick拷贝构造函数,触发C2280错误。

修复方案

方案1:使用智能指针存储对象(推荐)

将容器改为存储std::unique_ptr<Brick>,避免直接拷贝Brick对象:

  1. 修改Bricks.h中容器定义:
std::vector<std::unique_ptr<Brick>> brickArr;
  1. 修改Bricks.cpp中添加元素的代码:
brickArr.push_back(std::make_unique<Brick>(rowSpacing, columnsSpacing, (const char*)brickPlan[index], renderer));

智能指针的移动操作是合法的,容器存储指针而非对象,彻底规避拷贝问题。

方案2:为Brick类实现移动语义

若希望容器直接存储对象,可让Brick支持移动构造(前提是TinyXML的XMLDocument支持移动):

  1. 在Brick.h中声明移动构造与移动赋值运算符:
Brick(Brick&&) noexcept;
Brick& operator=(Brick&&) noexcept;
  1. 在Brick.cpp中默认实现(若XMLDocument支持移动):
Brick::Brick(Brick&&) noexcept = default;
Brick& Brick::operator=(Brick&&) noexcept = default;
  1. 修改push_back调用为移动语义:
brickArr.push_back(std::move(brick));

方案3:重构XML加载逻辑(优化性能)

每个Brick构造时重复加载同一个XML文件是冗余操作,可将XML解析逻辑移到Bricks类中:

  1. 定义一个结构体存储砖块配置数据:
struct BrickData {
    int hitPoints;
    int breakScore;
    std::string texturePath;
};
  1. 在Bricks::Init中先加载XML,解析所有BrickType数据并存储到映射中:
std::unordered_map<std::string, BrickData> brickTypeMap;
// 解析XML并填充brickTypeMap的逻辑
  1. 修改Brick类,移除XMLDocument成员,构造函数直接接收BrickData:
Brick(int rowSpacing, int columnSpacing, const BrickData& data, SDL_Renderer* renderer);
  1. 创建Brick时从映射中获取数据,避免每个砖块重复加载XML。

这种方案既解决了拷贝问题,又减少了IO操作,提升程序性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 21:40:57