现代c++的演变越来越去指针化,智能指针的完善,目标就是让开发者可以不再管理内存的释放问题,就再也不用malloc/free,new/delete之类了。智能指针包括unique_ptr,shared_ptr,weak_ptr,使用时引用头文件#include <memory>。
unique_ptr的使用,罗列起来比较琐碎:
class Student
{
public:
Student() {
cout << "constructor" << endl;
}
~Student() {
cout << "destructor" << endl;
}
private:
string name_;
int age_ = 0;
};
unique_ptr<Student> create_student() {
auto ptr = make_unique<Student>();
return ptr;
}
int main()
{
auto uptr = make_unique<int>(16);
cout << *uptr << endl;
auto uptr3 = move(uptr); //只能move
if (uptr) {
cout << "uptr" << endl;
}
if (uptr3) {
cout << "uptr3" << endl;
}
/////
auto uptr2 = make_unique<int[]>(8); //当是数组类型时,参数为数组长度
uptr2[0] = 100;
cout << uptr2[0] << " " << uptr2[1] << endl;
////
auto ptr = create_student();
ptr = nullptr; //手动释放
return 0;
}
shared_ptr是线程安全的,引用计数归零时,释放内存:
int main()
{
auto sptr = make_shared<Student>();
auto sptr2 = sptr;
auto sptr3 = sptr2;
cout << sptr.use_count() << endl; //3
cout << sptr2.use_count() << endl; //3
cout << sptr3.use_count() << endl; //3
sptr3 = nullptr;
cout << sptr.use_count() << endl; //2
cout << sptr2.use_count() << endl; //2
cout << sptr3.use_count() << endl; //0
return 0;
}
weak_ptr用得不多,它大体解决两个问题:
1. shared_ptr指向的对象随时可能会释放,采用弱引用后,对象的生命会延续到该弱引用释放为止
int main()
{
auto sptr = make_shared<Student>();
weak_ptr<Student> wptr = sptr;
cout << wptr.use_count() << " " << wptr.expired() << endl; //1 0
auto sptr2 = wptr.lock();
cout << wptr.use_count() << " " << wptr.expired() << endl; //2 0
sptr = nullptr;
cout << wptr.use_count() << " " << wptr.expired() << endl; //1 0
if (sptr2) {
cout << "available" << endl; //available
}
return 0;
}
2. 解决循环引用的释放问题
class Student
{
public:
Student() {
cout << "constructor" << endl;
}
~Student() {
cout << "destructor" << endl;
}
void set_st(shared_ptr<Student>& st) {
st_ = st;
}
void set_wst(shared_ptr<Student>& wst) {
wst_ = wst;
}
private:
string name_;
int age_ = 0;
shared_ptr<Student> st_;
weak_ptr<Student> wst_;
};
int main()
{
auto sptr = make_shared<Student>();
sptr->set_st(sptr); //循环引用
return 0;
}
执行该代码会发现,对象并没有释放,也就是出现了内存泄漏。使用弱引用就可以正常释放,因为weak_ptr是不会修改引用计数的:
int main()
{
auto sptr = make_shared<Student>();
sptr->set_wst(sptr);
return 0;
}