动机
使用堆区内存时,往往需要new分配指针,使用结束后要用delete回收内存,如果忘记delete就会造成内存泄漏。这样的手动管理是一种负担,智能指针会自动回收内存。
c++ 11 中常用的3种智能指针:C++11 引入了 3 个智能指针类型:
std::unique_ptr<T>
:独占资源所有权的指针。std::shared_ptr<T>
:共享资源所有权的指针。std::weak_ptr<T>
:共享资源的观察者,需要和 std::shared_ptr 一起使用,不影响资源的生命周期。
可以看作指针的封装类,创建时将new得到的地址赋给智能指针,过期时(对象销毁)在析构函数中释放堆区内存。
示例
头文件:#include <memory>
#include <iostream>
#include <string>
#include <memory> // auto_ptr,unique_ptr,shared_ptr
#include <vector>
#include <algorithm> //for_each
#include <assert.h>
using namespace std;
unique_ptr<string> demo(const char*s);
unique_ptr<int> make_int(int n);
void show(unique_ptr<int> &p);//pass by reference
int main(){
// auto_ptr
{
auto_ptr<double> p1(new double(2.0));
/*
auto_ptr<double> p2;
p2 = p1; // pass compiler, run-time error
// delete twice
cout << " *p2=" << *p2 << " ,*p1=" << *p1 << "\n";
*/
}
// unique_ptr
{
//assign by std::move
unique_ptr<string> p1 = std::make_unique<string>("hello");
unique_ptr<string> p2;
p2 = std::move(p1);
assert(p1 == nullptr);//p1 is null
p1 = std::make_unique<string>("world");
cout << *p1 << " , " << *p2 << "\n";
//assign with temp unique_ptr
unique_ptr<string> p3;
p3 = demo("tmp ptr"); // tmp unique_ptr deconstruct
cout<<*p3<<"\n";
//point to array : equal to new[]
unique_ptr<int[]> p2arr = std::make_unique<int[]>(20);
for(int i=0;i<20;i++) p2arr[i] = i*i;
for (int i = 0; i < 20; i++)
cout<<p2arr[i]<<" ";
cout << "\n";
// used in std::vector
int len = 10;
vector<unique_ptr<int>> vp(len);
for (int i = 0; i < len; i++)
vp[i] = make_int(i); // copy temporary unique_ptr
vp.push_back(make_int(20)); // ok, temporary unique_ptr
for_each(vp.begin(), vp.end(), show); // print
cout << "\n";
}
// shared_ptr
{
shared_ptr<int> p1(new int(5));
shared_ptr<int> p2;
p2 = p1; //ok, reference count
cout << *p1 << " , " << *p2 << "\n";
shared_ptr<int> p3;
p3=make_int(10);//ok, unique_ptr is a rvalue
cout << *p3 << "\n";
p1=make_int(20);
cout << *p1 << " , " << *p2 << "\n";
}
}
unique_ptr<string> demo(const char* s){
unique_ptr<string> tmp(new string(s));
return tmp;
}
unique_ptr<int> make_int(int n){
return unique_ptr<int>(new int(n));
}
void show(unique_ptr<int> &p){
cout<<*p<<" ";
}