C++11中智能指针包括三种:共享指针(shared_ptr),独占指针(unique_ptr),弱指针(weak_ptr)。
智能指针通过计数原理来实现,但在使用过程中可能会出现循环引用的问题,我们可以通过weak_ptr去解决。
出现循环引用的举例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| #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; cout << c.use_count() << endl; } cout << wpp.use_count() << endl; cout << wpc.use_count() << endl; return 0; }
|
在如下例子中定义了两个类 Parent、Child,在两个类中分别定义另一个类的对象的共享指针,由于在程序结束后,两个指针相互指向对方的内存空间,导致内存无法释放。
使用weak_ptr解决循环引用
因为weak_ptr的作用是绑定到一个智能指针上,但不会影响该指针的计数,所以我们只需要在原本的循环引用中,令其中一环为weak_ptr即可打破这个闭环。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| #include <iostream> #include <memory>
using namespace std;
class Child; class Parent;
class Parent { private: weak_ptr<Child> ChildPtr; public: void setChild(shared_ptr<Child> child) { this->ChildPtr = child; }
void doSomething() { 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; cout << c.use_count() << endl; } cout << wpp.use_count() << endl; cout << wpc.use_count() << endl; return 0; }
|
为什么在访问weak_ptr所指的对象时,要先转为shared_ptr?