C++11新特性——智能指针(二)
1、shared_ptr
-
初始化
-
构造函数
-
class Person { public: Person(int v) { no = v; cout << "Construct" << no << endl; } ~Person() { cout << "Destruct" << no << endl; } int no; }; class DestructPerson { public: void operator()(Person* pt) { cout << "DestructPerson" << endl; delete pt; } }; int main() { shared_ptr<Person> sp1;//空的shared_ptr,可以指向类型为Person的对象 shared_ptr<Person> sp2(new Person(2)); //定义shared_ptr, 同时指向类型为T的对象 // 1 cout << "sp2.use_count(): " << sp2.use_count() << endl;//当前管控Person(2)的共享指针的数量 sp1 = sp2; // 2 cout << "sp2.use_count(): " << sp1.use_count() << endl;//当前管控Person(2)的共享指针的数量 shared_ptr<Person> sp3(sp1); // 3 cout << "sp2.use_count(): " << sp3.use_count() << endl;//当前管控Person(2)的共享指针的数量 //数组对象的管理 shared_ptr<Person[]> sp4(new Person[5]{3,4,5,6,7});//delete[] shared_ptr<Person> sp8(new Person(8), DestructPerson());//调用DestructPerson()释放对象 system("pause"); return 0; }
-
-
使用make_shared初始化对象,分配内存效率更高
-
make_shared
函数的主要功能是在动态内存中分配一个对象并初始化它,返回指向此对象的shared_ptr
-
//make_shared<类型>(构造类型对象需要的参数列表); shared_ptr<int> p4 = make_shared<int>(2);//多个参数以逗号隔开,最多接受十个 shared_ptr<string> = make_shared<string>("字符串"); //使用make_shared 函数模板初始化 shared_ptr<Person> sp9; sp9 = make_shared<Person>(9); cout << "after sp9 = make_shared<Person>(9),ref_counter: " << sp9.use_count() << endl;// 1
-
-
-
其他
-
//主动释放对象 shared_ptr<Person> up1 = make_shared<Person>(9); //up1 = nullptr; shared_ptr<Person> upx = up1; Person* up = new Person(10); //重置 //up1.reset();//将up1重置为空指针,所管理对象引用计数 减1 up1.reset(up);//将up1重置为up的值,up1管控的对象计数减1,up1接管对up指针的管控,up1被析构掉了 //up1.reset(up,d));//将up1重置为up的值,up1管控的对象计数减1 并使用d作为删除器 cout << up1.use_count() << endl; cout << "交换前,up1: " << up1->no << "sp10: " << upx->no << endl;//10 9 swap(upx, up1); cout << "交换后,up1: " << up1->no << "sp10: " << upx->no << endl;//9 10
-
-
使用陷阱
-
shared_ptr作为被管控的对象的成员时,小心因循环引用造成无法释放资源
-
class boy { public: boy() { cout << "boy construct!" << endl; } ~boy() { cout << "boy destruct!" << endl; } void set_girl_friend(shared_ptr<girl>& g) { girl_friend = g; } private: shared_ptr<girl> girl_friend; }; class girl { public: girl() { cout << "girl construct!" << endl; } ~girl() { cout << "girl destruct!" << endl; } void set_boy_friend(shared_ptr<boy>& b) { boy_friend = b; } private: shared_ptr<boy> boy_friend; }; void use_trap() { shared_ptr<girl> sp_girl(new girl());//白娘子 shared_ptr<boy> sp_boy(new boy());//许仙 sp_girl->set_boy_friend(sp_boy); sp_boy->set_girl_friend(sp_girl); /* girl construct! boy construct! */ //没有被析构!!! }
-
weak_ptr
class girl;
class boy {
public:
boy() {
cout << "boy construct!" << endl;
}
~boy() {
cout << "boy destruct!" << endl;
}
void set_girl_friend(shared_ptr<girl>& g) {
girl_friend = g;
}
private:
weak_ptr<girl> girl_friend; //****************lock*******************
};
class girl {
public:
girl() {
cout << "girl construct!" << endl;
}
~girl() {
cout << "girl destruct!" << endl;
}
void set_boy_friend(shared_ptr<boy>& b) {
boy_friend = b;
}
private:
shared_ptr<boy> boy_friend;
};
void use_trap() {
shared_ptr<girl> sp_girl(new girl());//白娘子
shared_ptr<boy> sp_boy(new boy());//许仙
//弱指针的使用
weak_ptr<girl> wp_girl; //定义空的弱指针
weak_ptr<girl> wp_girl2(sp_girl);//使用共享构造
wp_girl = sp_girl; //允许共享指针赋值给弱指针
//weak_ptr<boy> wp_boy;
cout << "sp_girl ref_count: " << sp_girl.use_count() << endl;// 1
cout << "wp_girl ref_count: " << wp_girl.use_count() << endl;// 1
//(*sp_girl).set_boy_friend(sp_boy); 弱指针不支持* 和 -> 对指针访问
//sp_girl->set_boy_friend(sp_boy);
//在必要时可以转成共享指针
shared_ptr<girl> sp_girl1;
sp_girl1 = wp_girl.lock();
cout << "after lock, wp_girl ref_count: " << wp_girl.use_count() << endl;// 2
sp_girl1 = NULL;
sp_girl->set_boy_friend(sp_boy);
sp_boy->set_girl_friend(sp_girl);
/*
girl construct!
boy construct!
*/
//没有被析构!!!避免交叉使用或者把一个设置为弱指针
}