C++ 使用智能指针会出现什么问题?怎么解决?
智能指针可能出现的问题:循环引用
在如下例子中定义了两个类 Parent、Child,在两个类中分别定义另一个类的对象的共享指针,由于在程序结束后,两个指针相互指向对方的内存空间,导致内存无法释放。
#include <iostream> #include <memory> using namespace std; class Child; class Parent; class Parent { private: shared_ptr<Child> ChildPtr; public: void setChild(shared_ptr<Child> child) { this->ChildPtr = child; } void doSomething() { if (this->ChildPtr.use_count()) { } } ~Parent() {} }; class Child { private: shared_ptr<Parent> ParentPtr; public: void setPartent(shared_ptr<Parent> parent) { this->ParentPtr = parent; } void doSomething() { if (this->ParentPtr.use_count()) { } } ~Child() {} }; int main() { weak_ptr<Parent> wpp; weak_ptr<Child> wpc; { shared_ptr<Parent> p(new Parent); shared_ptr<Child> c(new Child); p->setChild(c); c->setPartent(p); wpp = p; wpc = c; cout << p.use_count() << endl; // 2 cout << c.use_count() << endl; // 2 } cout << wpp.use_count() << endl; // 1 cout << wpc.use_count() << endl; // 1 return 0; }
循环引用的解决方法: weak_ptr
循环引用:该被调用的析构函数没有被调用,从而出现了内存泄漏。
weak_ptr 对被 shared_ptr 管理的对象存在非拥有性(弱)引用,在访问所引用的对象前必须先转化为 shared_ptr;
weak_ptr 用来打断 shared_ptr 所管理对象的循环引用问题,若这种环被孤立(没有指向环中的外部共享指针),shared_ptr 引用计数无法抵达 0,内存被泄露;令环中的指针之一为弱指针可以避免该情况;
weak_ptr 用来表达临时所有权的概念,当某个对象只有存在时才需要被访问,而且随时可能被他人删除,可以用 weak_ptr 跟踪该对象;需要获得所有权时将其转化为 shared_ptr,此时如果原来的 shared_ptr 被销毁,则该对象的生命期被延长至这个临时的 shared_ptr 同样被销毁。
#include <iostream> #include <memory> using namespace std; class Child; class Parent; class Parent { private: // shared_ptr<Child> ChildPtr; weak_ptr<Child> ChildPtr; public: void setChild(shared_ptr<Child> child) { this->ChildPtr = child; } void doSomething() { // new shared_ptr if (this->ChildPtr.lock()) { } } ~Parent() {} }; class Child { private: shared_ptr<Parent> ParentPtr; public: void setPartent(shared_ptr<Parent> parent) { this->ParentPtr = parent; } void doSomething() { if (this->ParentPtr.use_count()) { } } ~Child() {} }; int main() { weak_ptr<Parent> wpp; weak_ptr<Child> wpc; { shared_ptr<Parent> p(new Parent); shared_ptr<Child> c(new Child); p->setChild(c); c->setPartent(p); wpp = p; wpc = c; cout << p.use_count() << endl; // 2 cout << c.use_count() << endl; // 1 } cout << wpp.use_count() << endl; // 0 cout << wpc.use_count() << endl; // 0 return 0; }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论