智能指针可能出现的问题:循环引用
在如下例子中定义了两个类 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;
}
评论列表 (0条):
加载更多评论 Loading...