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
相关产品推荐
相关产品推荐

