楼主: Daphne1209
22 0

[作业] 【C++进阶】Day 5:RobotManager 系统 (指针容器与内存生命周期) [推广有奖]

  • 0关注
  • 0粉丝

等待验证会员

学前班

40%

还不是VIP/贵宾

-

威望
0
论坛币
0 个
通用积分
0
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
20 点
帖子
1
精华
0
在线时间
0 小时
注册时间
2018-11-11
最后登录
2018-11-11

楼主
Daphne1209 发表于 昨天 17:07 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

前言

今天的 C++ 学习难度明显提升了一个层次。之前的学习内容主要集中在变量定义和基础逻辑的实现上,而今天则需要动手实现一个模拟真实场景的机器人管家系统,以应对更复杂的工程需求。

RobotManager

本次实践涉及多个核心概念:包括指针存储动态内存分配(使用 new 和 delete)以及通过迭代器进行容器遍历。虽然整个过程逻辑较为复杂,理解起来有一定挑战,但当看到析构函数自动完成内存清理时,终于体会到了 C++ 在系统级编程中的精妙与美感。

new/delete

一、为何要采用如此复杂的机制?

通过本次实战,总结出两个关键原因:

  • 效率优先:机器人对象本身可能非常庞大,例如包含地图数据、雷达信息等。如果直接在容器中存储完整对象,在容器扩容时会触发大量对象的复制操作,带来高昂的性能开销。而改用指针存储后,每个元素仅占 8 字节(64 位系统下的地址大小),极大地减轻了“搬家”成本。
  • 生命周期精准控制:通过结合 newdelete 使用指针,可以精确掌控机器人对象的创建与销毁时机,避免依赖默认的栈生命周期管理,从而适应更复杂的运行场景。
new
delete

二、系统架构设计

整个系统由两个核心类构成:

  • Robot 类:代表单个机器人实体,具备自我介绍等功能。
  • Manager 类:作为机器人集群的管理中心,负责对机器人进行增、删、查、改操作。
Robot
RobotManager

核心难点:管家类的实现

其中,Manager 类的设计尤为关键,尤其是在处理堆内存资源和迭代器安全删除方面,稍有不慎就会导致内存泄漏或访问非法地址。

RobotManager.h
class RobotManager {
public:
    RobotManager();
    ~RobotManager(); // 【析构函数】管家下班时的自动清理逻辑

    void add_robot(int id, std::string name); // 动态生成
    void delete_robot(int id); // 手动销毁
    void tick_all(); // 全体巡检

private:
    // 这里存的是 Robot* (指针),而不是 Robot 本体
    std::vector<Robot*> robot_list_; 
};

三、关键代码逻辑解析(避坑经验总结)

以下三个部分是本次编码中最容易出错的地方,为了便于理解,我引入“酒店管理”的比喻来进行说明。

1. 动态创建对象(new)—— 相当于“办理入住”

每当新增一个机器人,就需要使用 new 在堆上为其分配内存空间,就像为客人分配房间并登记入住信息一样。

void RobotManager::add_robot(int id, std::string name) {
    // 1. 在堆内存(Heap)申请房间,new 返回的是房间号(地址)
    Robot* new_bot = new Robot(id, name);
    
    // 2. 把房间号登记在册
    robot_list_.push_back(new_bot);
}

2. 安全释放资源(delete + erase)—— 对应“退房流程”

这是整个程序中最容易出错的部分,特别是在遍历过程中删除元素时,必须借助迭代器(Iterator)来正确操作。

void RobotManager::delete_robot(int id) {
    // 使用迭代器 it 进行遍历
    for (auto it = robot_list_.begin(); it != robot_list_.end(); ) {
        Robot* current_bot = *it; // 拿到当前房间号

        if (current_bot->get_id() == id) {
            // 【关键步骤 1】先释放内存!(把客人赶走)
            // 如果不写这行,只是把名单划掉,内存就泄漏了
            delete current_bot; 
            
            // 【关键步骤 2】从列表中移除
            // erase 会返回下一个有效的迭代器,保证循环不断链
            it = robot_list_.erase(it);
            return;
        } else {
            ++it; // 继续往下找
        }
    }
}

重要提醒:绝不能先执行 erase 再调用 delete!这相当于先把客人的名字从名单上划掉,再去尝试关闭房间电源——此时已无法找到对应房间号,导致该内存块永远无法被回收,形成内存泄漏。

erase
delete

3. 析构函数的自动清理 —— 好比“酒店倒闭”

最令人印象深刻的是析构函数的作用。当 main() 函数结束,Manager 对象即将被销毁时,析构函数会自动触发。

main
manager

它会遍历所有残留的指针,并逐一释放其所指向的内存空间。这种机制正是 C++ 中著名的 RAII(Resource Acquisition Is Initialization) 思想的体现:

你只需关注资源的申请,系统的初始化即意味着资源的绑定;而对象生命周期结束时,析构过程自然完成资源的释放。
RobotManager::~RobotManager() {
    std::cout << "[系统] 管家即将下班,清理残余机器人..." << std::endl;
    for (auto ptr : robot_list_) {
        delete ptr; // 把还没退房的客人全部清退
    }
    robot_list_.clear();
}
new

四、运行效果展示

完成编译并执行程序后,终端输出如下结果:

五、学习总结

  • 熟练掌握 指针(*)取地址符(&) 的使用方式及其相互关系。
  • 理解堆内存管理的基本原则:谁申请(new),谁释放(delete),防止资源泄露。
  • 深入认识容器中存储指针的优势,特别是在处理大型对象和动态集合时的性能表现。
*
&
vector
Robot
std::vector
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:Manager Manage robot 生命周期 Day

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
jg-xs1
拉您进交流群
GMT+8, 2025-12-6 09:05