c/c++ 智能指针 weak_ptr 使用
程序员文章站
2022-06-11 18:37:40
智能指针 weak_ptr 使用 weak_ptr用途: 1,解决空悬指针问题 2,解决循环引用问题 weak_ptr特点:没有 操作和 操作 weak_ptr是不控制所指对象生存周期的智能指针,它指向由一个shared_ptr管理的对象。将一个weak_ptr绑定到一个shared_ptr不会改变 ......
智能指针 weak_ptr 使用
weak_ptr用途:
1,解决空悬指针问题
2,解决循环引用问题
weak_ptr特点:没有*操作和->操作
weak_ptr是不控制所指对象生存周期的智能指针,它指向由一个shared_ptr管理的对象。将一个weak_ptr绑定到一个shared_ptr不会改变shared_ptr的计数器。一旦最后一个指向对象的shared_ptr被销毁,对象就会被释放,即使有weak_ptr指向这个对象,对象也会被释放。
一,先来个表格,唠唠weak_ptr
操作 | 功能描述 |
---|---|
weak_ptr<t> w | 空weak_ptr,可以指向类型为t*的对象。 |
weak_ptr<t> w(sp) | 与shared_sp sp指向相同对象的weak_ptr。t必须能转换为sp所指的类型。 |
w = p | p可以是一个shared_ptr或一个weak_ptr。赋值后w指向p所指的对象。 |
w.reset() | 将w置为空 |
w.use_count() | 与w共享对象的shared_ptr的数量 |
w.expired() | 若w.use_count()为0,返回true,否则返回false |
w.lock() | 如果expired()为true,返回一个空shared_ptr;否则返回一个指向w所指对象的shared_ptr。 |
小例子索引
代码块 | 功能描述 |
---|---|
test1 | weak_ptr不增加引用计数 |
test2 | weak_ptr没有->和*操作 |
test3 | lock使用 |
test4 | 循环引用,导致即使是智能指针也不能释放内存。用weak_ptr解决了循环引用,导致的内存不能释放的问题 |
小例子
#include <iostream> #include <memory> #include <vector> using namespace std; class test{ public: test(int d = 0) : data(d){cout << "new" << data << endl;} ~test(){cout << "del" << data << endl;} void func(){cout << "func" << endl;} private: int data; }; //test4 循环引用,导致即使是智能指针也不能释放内存 class teacher; class student; class teacher{ public: teacher(){cout << "teacher()" << endl;} ~teacher(){cout << "del teacher" << endl;} shared_ptr<student> stu; }; class student{ public: student(){cout << "student()" << endl;} ~student(){cout << "del student" << endl;} //如果换成shared_ptr<teacher> tea;就会形成循环引用,导致内存泄漏 weak_ptr<teacher> tea; }; int main(){ //test1 weak_ptr不增加引用计数 /* shared_ptr<test> sp1 = make_shared<test>(1); cout << sp1.use_count() << endl;//1 weak_ptr<test> wp1 = sp1; cout << wp1.use_count() << endl;//1 */ //test2 weak_ptr没有->和*操作 //wp1->func(); //(*wp1).func(); //test3 lock使用 /* shared_ptr<int> sptr; sptr.reset(new int); *sptr = 10; weak_ptr<int> weak1 = sptr; sptr.reset(new int); *sptr = 5; weak_ptr<int> weak2 = sptr; // weak1 is expired! if(auto tmp = weak1.lock()) cout << *tmp << '\n'; else cout << "weak1 is expired\n"; // weak2 points to new data (5) if(auto tmp = weak2.lock()) cout << *tmp << '\n'; else cout << "weak2 is expired\n"; */ //test4 循环引用,导致即使是智能指针也不能释放内存 //用weak_ptr解决了循环引用,导致的内存不能释放的问题 shared_ptr<teacher> tptr(new teacher);//计数器1 shared_ptr<student> sptr(new student);//计数器1 tptr->stu = sptr;//sptr的计数器2 sptr->tea = tptr;//不增加tptr的引用计数,因为tea是weak指针 cout << tptr.use_count() << endl;//1 cout << sptr.use_count() << endl;//2 return 0; }