C++中std::vector存储堆分配对象指针而非直接存对象的原因
这种写法在游戏开发的特定场景下确实存在合理的设计考量,常见的理由有以下几点:
- 保证对象地址稳定性:
std::vector扩容时会重新申请更大的连续堆内存,将原有元素全部拷贝/移动到新地址后释放旧内存,这会导致之前存储的Archetype对象的指针、引用全部失效。ECS 体系中往往有大量其他模块(比如实体实例、组件查询逻辑)需要长期持有Archetype的引用,单独在堆上分配Archetype存指针,就能保证只要对象不被销毁,地址就不会变化,完全规避野指针风险。 - 降低vector扩容开销:如果
Archetype类本身体积较大(比如内部存储了大量组件块的元数据、动态数组等),std::vector扩容时批量拷贝/移动Archetype对象的成本会非常高。而存储指针时,扩容只需要拷贝固定大小的指针(64位系统下仅8字节),开销可以忽略不计。如果Archetype本身是不可拷贝、不可移动的类型,直接存对象的写法根本无法编译通过。 - 内存操作灵活性更高:如果需要单独销毁某一个闲置的
Archetype,存指针时只需要delete对应对象再移除vector里的元素即可,不需要触发其他Archetype对象的移动操作。另外即使当前没有用到多态,这种写法也预留了后续扩展Archetype子类的可能性,改动成本极低。
当然如果你的场景里Archetype体积很小,也不需要外部长期持有Archetype的指针/引用,那直接存对象的写法显然更优:不需要手动管理内存,避免内存泄漏风险,而且连续存储的缓存局部性更好,遍历访问的性能更高。
内容的提问来源于stack exchange,提问作者JensB
相关产品推荐
相关产品推荐

