在Application与Graphics类关联场景中如何使用智能指针?
问题解答
先明确你的代码结构:
头文件代码
#include <memory> class Application; class Graphics { private: const Application* _prApplication;//This is a reference pointer to a Application... public: Graphics(const Application* prApplication); ~Graphics(void); }; class Application { private: std::unique_ptr<Graphics> _graphics; public: Application(void); ~Application(void); };
CPP文件代码
Application::Application(void) { _graphics = std::make_unique<Graphics>(this); } Application::~Application(void) { //NOTHING HERE... } Graphics::Graphics(const Application* prApplication) { _prApplication = prApplication; } Graphics::~Graphics(void) { _prApplication = nullptr; // 注:原代码存在拼写错误,修正为_prApplication }
1. _prApplication是否应该改为weak_ptr?
取决于实际场景:
- 如果Graphics的生命周期始终短于Application(比如当前代码中,Graphics完全由Application的
unique_ptr持有,Application销毁时会优先销毁Graphics),用裸指针是安全的,没必要改成weak_ptr。 - 如果存在Graphics可能比Application晚销毁的情况(也就是你假设的场景),那必须改成
weak_ptr,避免野指针风险。
2. Application销毁后,未销毁的Graphics中的_prApplication会不会变成野指针?
会。当堆上的Application实例被销毁,它占用的内存会被回收,此时Graphics里的_prApplication指向的是已释放的内存,成为野指针。任何对该指针的访问都会触发未定义行为,比如程序崩溃、数据错乱等。
3. 这种场景下能否使用智能指针,该如何实现?
可以通过智能指针实现安全的对象引用,需要调整代码结构:
步骤1:让Application继承std::enable_shared_from_this
修改头文件:
#include <memory> class Application; class Graphics { private: std::weak_ptr<const Application> _prApplication; public: Graphics(const std::weak_ptr<const Application>& prApplication); ~Graphics(void); // 示例:安全访问Application的方法 void doSomething() { if (auto app = _prApplication.lock()) { // 此时app是有效的shared_ptr,可安全访问Application对象 } else { // Application已销毁,执行相应的容错逻辑 } } }; class Application : public std::enable_shared_from_this<Application> { private: std::unique_ptr<Graphics> _graphics; public: Application(void); ~Application(void); };
步骤2:修改构造逻辑,传递shared_from_this()
修改CPP文件:
Application::Application(void) { // 注意:Application必须由std::shared_ptr管理,否则shared_from_this会报错 _graphics = std::make_unique<Graphics>(shared_from_this()); } Application::~Application(void) { } Graphics::Graphics(const std::weak_ptr<const Application>& prApplication) : _prApplication(prApplication) { } Graphics::~Graphics(void) { }
关键注意事项:
- 必须用
std::shared_ptr创建Application实例,不能直接在栈上声明(比如Application app;会导致shared_from_this()行为异常),正确创建方式:auto app = std::make_shared<Application>(); - 访问
_prApplication时,必须先调用lock()获取shared_ptr,返回空则说明Application已销毁,不能再访问原对象。
内容的提问来源于stack exchange,提问作者Weiner Lemes
相关产品推荐
相关产品推荐

