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

C++如何创建含引用成员与指针向量的Entity类并实现深拷贝

Entity类实现方案

首先先给出完整的Entity类定义,默认你使用的Rectangle是支持值语义、可直接拷贝的普通结构体/类:

#include <vector>
#include <algorithm>
#include "Component.h" // 你存放Component类定义的头文件

// 此处假设Rectangle的定义如下,你可以替换为自己已有的实现
struct Rectangle {
    float x1 = 0.f, y1 = 0.f, x2 = 0.f, y2 = 0.f;
};

class Entity {
private:
    Rectangle rect;
    std::vector<Component*> components;
public:
    // 默认构造函数
    Entity() = default;
    // 带Rectangle参数的自定义构造函数
    explicit Entity(const Rectangle& r) : rect(r) {}

    // 1. 析构函数:释放所有持有的Component实例
    ~Entity() {
        for (auto comp : components) {
            delete comp;
        }
        components.clear();
    }

    // 2. 拷贝构造函数:深拷贝所有Component实现实例独立
    Entity(const Entity& other) {
        // 值类型直接拷贝矩形属性
        rect = other.rect;
        // 遍历原Entity的组件,调用Clone方法创建独立副本
        components.reserve(other.components.size());
        for (auto comp : other.components) {
            components.push_back(comp->Clone());
        }
    }

    // 3. 拷贝赋值运算符重载:用copy-and-swap idiom实现异常安全的深拷贝
    Entity& operator=(Entity other) {
        swap(*this, other);
        return *this;
    }

    // 辅助交换函数,为copy-and-swap逻辑服务
    friend void swap(Entity& first, Entity& second) noexcept {
        using std::swap;
        swap(first.rect, second.rect);
        swap(first.components, second.components);
    }

    // 公共工具接口,可根据需求扩展
    void AddComponent(Component* comp) {
        components.push_back(comp);
    }

    const Rectangle& GetRect() const { return rect; }
    void SetRect(const Rectangle& newRect) { rect = newRect; }

    template<typename T>
    T* GetComponent() const {
        for (auto comp : components) {
            if (auto castComp = dynamic_cast<T*>(comp)) {
                return castComp;
            }
        }
        return nullptr;
    }
};
疑问解答
  • 是否需要单独编写拷贝构造函数、赋值运算符重载函数和析构函数?
    必须单独实现。你的Entity类持有指向Component派生类实例的裸指针,编译器默认生成的拷贝构造、拷贝赋值都是浅拷贝,只会复制指针地址,不会生成新的组件实例,会导致多个Entity共享同一份组件,而且析构的时候会出现同一块内存被多次释放的崩溃问题。
  • 实现Entity深拷贝是否必须同时实现这三个函数?
    是的,符合C++的三法则要求:如果类需要自定义析构函数、自定义拷贝构造函数、自定义拷贝赋值运算符三者中的任意一个,那么你大概率需要同时实现另外两个。对于你这个场景,析构要释放组件内存、拷贝构造要深拷贝组件、赋值运算符要避免浅拷贝,三者缺一不可。
  • 额外优化建议:如果使用C++11及以上版本,可以将Component*替换为std::unique_ptr<Component>,能自动管理内存,减少手动释放的出错概率,不过深拷贝逻辑还是需要自己手动实现,因为智能指针的默认拷贝行为是禁止拷贝unique_ptr,或者浅拷贝shared_ptr,都不符合你要独立组件实例的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 05:24:05