如何使用智能指针让Person类持有外部Student对象引用以避免内存泄漏?
解决方案:用智能指针管理Student对象
先修正原代码的语法问题,再根据你的需求分场景实现智能指针的正确使用:
场景1:Person拥有Student对象的所有权
如果Person是这些Student对象的唯一管理者(比如getStudent方法中创建的对象仅由Person负责销毁),使用std::unique_ptr是最优选择,它会自动处理内存释放,彻底避免泄漏:
#include <iostream> #include <vector> #include <memory> #include <string> class Student { public: std::string studentName; Student(std::string name) : studentName(std::move(name)) {} }; class Person { public: std::vector<std::unique_ptr<Student>> collection; void getStudent() { std::cout << "input student name: "; std::string name; std::cin >> name; // 用make_unique创建智能指针,无需手动调用delete collection.push_back(std::make_unique<Student>(std::move(name))); } };
- 用
std::make_unique替代直接new,更安全且符合现代C++编码规范 - 当vector销毁、元素被移除时,
unique_ptr会自动释放对应的Student对象,无需手动管理内存
场景2:Person仅持有外部已存在对象的句柄(不拥有所有权)
如果Student对象是在代码其他位置创建并管理的,Person只需要持有句柄(不负责销毁),可以用std::weak_ptr配合外部的std::shared_ptr实现:
#include <iostream> #include <vector> #include <memory> #include <string> class Student { public: std::string studentName; Student(std::string name) : studentName(std::move(name)) {} }; class Person { public: std::vector<std::weak_ptr<Student>> collection; // 接收外部的shared_ptr,存入weak_ptr作为句柄 void addStudent(const std::shared_ptr<Student>& student) { collection.push_back(student); } // 使用时先通过lock()转换为shared_ptr,确保对象未被销毁 void printStudents() { for (auto& wp : collection) { if (auto sp = wp.lock()) { std::cout << sp->studentName << std::endl; } else { std::cout << "该Student对象已被销毁" << std::endl; } } } }; // 外部创建并管理Student对象的示例 int main() { Person p; { auto student1 = std::make_shared<Student>("Alice"); p.addStudent(student1); // student1离开作用域后会自动销毁,Person中的weak_ptr能检测到 } auto student2 = std::make_shared<Student>("Bob"); p.addStudent(student2); p.printStudents(); return 0; }
- 外部用
std::shared_ptr管理Student对象的生命周期 - Person用
std::weak_ptr存储句柄,不会影响对象的销毁时机,同时能通过lock()检查对象是否仍存在 - 完全匹配你“持有其他位置存在的对象的句柄”的需求,且无内存泄漏风险
关键注意点
- 尽量避免在容器中存储原始指针,除非你能确保手动处理所有内存释放逻辑,智能指针是更可靠的选择
- 根据所有权关系选择对应智能指针:唯一所有权用
unique_ptr,共享所有权用shared_ptr,仅观察对象用weak_ptr
内容的提问来源于stack exchange,提问作者RMC_DEV
相关产品推荐
相关产品推荐

