C++如何使用指针管理游戏中的实体对象

陌芳大大_1238

陌芳大大_1238

2026-08-20

349人浏览

原创

用 raw 指针管理实体易导致悬空指针或重复释放,因其无所有权语义;应优先用 std::unique_ptr 独占管理,共享场景慎用 std::shared_ptr,大规模系统推荐 entityid + 查表机制。

c++如何使用指针管理游戏中的实体对象

用 raw 指针管理实体对象为什么容易出问题

直接用 Entity* 存储游戏实体(比如敌人、道具)看似简单,但极易导致悬空指针或重复释放。典型场景是:A 系统删除了 enemy1,B 系统还在用它的指针调用 update() —— 程序立刻崩溃或行为不可预测。

根本原因不是指针本身错,而是 raw 指针不携带所有权语义,编译器和运行时都不帮你检查生命周期。哪怕你加了 if (ptr) { ptr->update(); },也挡不住 ptr 指向已释放内存的“假非空”状态。

  • 不要把 raw 指针当“安全引用”用,尤其跨系统(渲染、物理、AI)传递时
  • 避免在容器里存裸指针(如 std::vector<entity></entity>),除非你能 100% 保证所有指针指向的对象生存期长于容器
  • 如果必须用 raw 指针(比如性能敏感的 inner loop),只用于短暂访问,且确保其来源是明确的所有者(如 EntityManager::get(id) 返回的引用包装器)

std::unique_ptr 是最常用的起点

当你需要一个实体由单一系统独占管理(比如关卡加载器创建并销毁本关所有敌人),std::unique_ptr<entity></entity> 是首选。它强制移动语义,杜绝浅拷贝误用,析构时自动 delete

示例:实体管理器内部用 std::vector<:unique_ptr>></:unique_ptr> 存储,对外只提供 ID 或 const 引用:

class EntityManager {
    std::vector<:unique_ptr>> entities_;
public:
    EntityId create(std::unique_ptr<entity> e) {
        entities_.push_back(std::move(e));
        return EntityId{entities_.size() - 1};
    }
    Entity& get(EntityId id) { return *entities_[id.index]; }
    const Entity& get(EntityId id) const { return *entities_[id.index]; }
};</entity></:unique_ptr>
  • std::unique_ptr 不支持拷贝,但支持移动——这正好匹配“实体创建后移交管理权”的逻辑
  • 对外暴露 Entity& 而非 Entity*,避免用户意外保存指针;若需临时指针,用 &mgr.get(id) 显式取地址
  • 注意:std::vector::erase() 会触发 unique_ptr 析构,自动清理内存,无需手动 delete

std::shared_ptr 只在真正需要共享所有权时用

比如一个特效粒子同时被渲染系统和音效系统持有:渲染要读位置,音效要读距离。这时两个系统都可能“认为自己负责生命周期”,std::shared_ptr 就比手工计数更可靠。

C++
C++

"空空如也"

下载

但代价明显:引用计数原子操作有开销;循环引用会导致内存泄漏(A 持有 B 的 shared_ptr,B 也持有 A 的)。

  • 优先用 std::weak_ptr 打破循环:比如 AI 系统观察目标,用 weak_ptr<entity></entity>,访问前调用 lock() 检查是否还存活
  • 避免在 hot path(如每帧 update 循环)中频繁调用 shared_ptr::lock() 或构造新 shared_ptr,考虑缓存或改用其他机制
  • 不要用 shared_ptr 管理全局唯一对象(如玩家角色),那属于设计信号:应该用单例或直接引用,而非共享所有权

实体 ID + 查表比指针更健壮

大型游戏引擎(Unity、Unreal)实际很少暴露原始指针给上层逻辑。它们用整数 ID(如 uint32_t)代替指针,运行时通过哈希表或稀疏数组查到实体数据。好处是:ID 不会悬空,序列化/网络同步天然友好,内存可重用(删除实体后 ID 可回收)。

最小可行实现可以是:

struct EntityId { uint32_t index; uint32_t generation; };
class EntityManager {
    std::vector<:unique_ptr>> pool_;
    std::vector<uint32_t> free_list_; // 空闲槽位索引
    std::vector<uint32_t> generations_; // 每个槽位的代数
};</uint32_t></uint32_t></:unique_ptr>
  • ID 中的 generation 字段用来检测“野 ID”:即使槽位被复用,旧 ID 的 generation 已不匹配,查表返回空或断言失败
  • 这种方案下,系统之间只传 EntityId,完全规避指针生命周期问题
  • 性能关键路径(如 ECS 的 component 访问)通常进一步优化为 SOA 布局和连续内存,此时连“查表”都尽量避免,而是用 archetype + chunk 索引

指针管理的本质不是语法选择,而是厘清谁创建、谁销毁、谁持有、谁只是临时访问。从 unique_ptr 入手,再根据具体共享需求谨慎升级到 shared_ptr 或彻底转向 ID 机制,比一开始就追求“通用智能指针方案”更实际。真正的坑往往不在指针类型,而在没想清楚实体的归属边界。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

在线游戏
在线游戏

海量精品小游戏合集,无需安装即点即玩,休闲益智、动作闯关应有尽有,秒开即玩,轻松解压,快乐停不下来

下载

相关标签:

c++指针 c++ c++编程

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
c++和c语言的区别有哪些
c++和c语言的区别有哪些

c++和c语言的区别:1、面向对象编程(OOP)支持不同;2、新增特性不同;3、标准库不同;4、编译方式不同;5、命名空间不同等等。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.14

2068

9

c++和python学习顺序推荐
c++和python学习顺序推荐

一般建议先学习C++,再学习Python,因为这样可以逐步从较为底层的编程语言向更高级的语言过渡。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

939

6

python和c++学习性价比分析
python和c++学习性价比分析

Python易于学习,广泛应用于Web开发、数据科学和人工智能等领域,但性能较低。C语言性能高,适用于对性能要求较高的场景,如游戏开发和系统编程,但学习曲线陡峭,错误处理复杂。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

367

5

c语言和c++一样吗
c语言和c++一样吗

c语言和c++是两种不同的编程语言,虽然有相似之处,但存在显著差异。c语言专注于过程式编程和系统级开发,以简洁、高效著称。c++作为c语言的超集,引入了面向对象编程,增强了代码组织和管理能力,但学习曲线也更陡峭。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

307

5

c语言和c++先学哪个好
c语言和c++先学哪个好

初学者选择学习c语言还是c++语言,需要根据个人学习目标、背景以及编程兴趣和预期应用方向来决定。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

346

5

c语言和c++的区别和联系
c语言和c++的区别和联系

c语言和c++是计算机科学领域应用广泛的编程语言。虽然它们有着相似的基础,但它们在语言类型、语法功能和内存管理方面存在着显著差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

560

5

c++软件中文更改教程
c++软件中文更改教程

对于 ide,可通过打开设置,找到语言设置,选择中文,并保存更改。对于非 ide 应用程序,可查找设置或选项,选择语言设置,更改为中文,并保存更改。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.21

1389

9

python和java和c++学习性价比分析
python和java和c++学习性价比分析

Python以其易学性、丰富的库和活跃的社区而著称,适合数据科学、人工智能和Web开发。Java以其跨平台性、企业级应用开发和Android应用开发而闻名。C++以其底层控制能力、高效性能和游戏开发而著称。选择哪种语言取决于个人兴趣、职业方向和特定需求。想了解更多python和java和c++的相关内容,可以阅读本专题下面的文章。

2024.03.22

1177

7

c++和c语言学习顺序推荐
c++和c语言学习顺序推荐

对于初学者,建议先学习C语言,掌握编程基础后再转入C++,便于理解面向对象编程概念。有编程经验者可直接学习C++,快速接触高级编程技术。想了解更多c++和c语言的相关内容,可以阅读本专题下面的文章。

2024.03.25

1305

9

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Conan 2 Essentials 免费课程
Conan 2 Essentials 免费课程

共0课时 | 0人学习

CMake 与 Conan 集成实践
CMake 与 Conan 集成实践

共0课时 | 0人学习

Conan 2 高级依赖模型介绍
Conan 2 高级依赖模型介绍

共0课时 | 0人学习