智能指针和普通指针的用法类似,只是不需要手动释放内存,而是通过智能指针自己管理内存的释放,这样就不用担心忘记释放内存从而导致内存泄漏了。
c++11提供了3种智能指针:std::shared_ptr;std::unique_ptr;std::weak_ptr,使用时需要引用头文件<memory>
1.shared_ptr
std::shared_ptr使用引用技术,每一个shared_ptr的拷贝都指向相同的内存。在最后一个shared_ptr析构的时候,内存才会释放。
1.1 初始化
可以通过构造函数、std::make_shared<T>辅助函数和rest方法来初始化
//shared_ptr的初始化
std::shared_ptr<int> p(new int(1));
std::shared_ptr<int> p2=p;
std::shared_ptr<int> ptr;
ptr.reset(new int(1));
std::shared_ptr<string> p3 = std::make_shared<string>();//优先使用make_shared来构造智能指针,更高效
不能将原始指针赋值到智能指针,下列示例是错误的
std::shared_ptr<int> p = new int(1);//error
reset方法:对于一个未初始化的智能指针,可以通过reset方法来初始化,当智能指针种有值的时候,调用reset会使引用技术减一。
1.2 获取原始指针
std::shared_ptr<int> p = std::make_shared<int>();
int *ptr = p.get();
1.3 指定删除器
智能指针初始化时可以指定删除器
void DeletePtr(int *p)
{
delete p;
p = NULL;
}
std::shared_ptr<int> p(new int , DeletePtr);
shared_ptr管理动态数组时,需要制定删除器。因为默认删除器不支持数组对象
方法一:可以使用lambda表达式来使用
std::shared_ptr<int> p(new int[3],[](int *p){delete [] p;});
方法二:使用std::default_delete作为删除器
std::shared_ptr<int> p(new int[3],std::default_delete<int []>());
方法三:封装一个类
std::shared_ptr<T> make_shared_array_ptr(size_t size)
{
return std::shared_ptr<T>(new T[size],std::default_delete<T[]>());
}
std::shared_ptr<int> ptr = make_shared_array_ptr<int>(10);
2. unique_ptr
unique_ptr是独占型指针,不允许复制,可以通过move函数返回给其他的unique_ptr
std::unique_ptr<int> p(new int);
std::unique_ptr<int> ptr=p;//error,
std::unique_ptr<int> ptr2=std::move(p);//success
可以直接指向数组
std::unique_ptr<int []> ptr(new int[10]);
ptr[0]=0;
3. weak_ptr
weak_ptr监视shared_ptr,不会使计数加一。没有重载*和->,不能操作资源。