使用指针时很容易出现内存泄漏,便引入了智能指针,c++ 11中主要有三类
- std::unique_ptr:独占资源指针,同一时刻只能有一个指针指向同一个对象
- std::shared_ptr:共享资源指针,同一时刻可以有多个指针指向同一个对象
- std::weak_ptr:用来解决shared_ptr相互引用导致的死锁问题
- auto_ptr:已经废弃
unique_ptr
头文件 #include <memcpy>
使用std::unique_ptr代替裸指针,在离开作用域时自动释放内存
std::unique_ptr的引用计数始终为1,其性能与裸指针几乎等同
初始化
unique_ptr是没有拷贝构造函数的,只支持右值拷贝构造
// 直接初始化
std::unique_ptr<int> ptr(new int(3));// make_unqiue
// 注:该方法是c++ 14才有的
std::unique_ptr<int> ptr = std::make_unique<int>(3);// std::move
// 移动语义初始化(实际上移动语义和匿名对象初始化最终都是调用右值拷贝构造函数)
std::unique_ptr<int> ptr1(new int(1));
std::unique_ptr<int> ptr2 = std::move(ptr1);// 还有一种错误初始化方式
std::unique_ptr<int> ptr1(new int(1));
std::unique_ptr<int> ptr2 = ptr1; // 报错,尝试应用已删除的函数
std::unique_ptr<int> ptr3(ptr1); // 报错,左值拷贝构造并未实现
成员函数
-
release()
释放,调用后智能指针和其所指向对象的联系再无联系,但是该内存仍然存在有效。它会返回裸指针,但是该智能指针被置空。
返回的裸指针我们可以手工delete来释放,也可以用来初始化另外一个智能指针,或者给另外一个智能指针赋值。std::unqiue_ptr<int> ptr1 = std::make_unique<int>(1); std::unique_ptr<int> ptr2(ptr1.release()); // 此时,ptr1 = nullptr
-
reset()
reset()不带参数情况:释放智能指针所指向的对象(释放因为它是独占,而不像shared_ptr还需要考虑引用计数),并将智能指针置空。
reset()带参数时:释放智能指针所指向的对象,并将该智能指针指向新对象. -
get()
返回智能指针中保存的裸指针
返回值裸指针与智能指针共同管理对象 -
swap()
交换两个对象的指向unique_ptr<string> ps1(new string("good luck")); unique_ptr<string> ps2(new string("good luck2")); ps1.swap(ps2); std::swap(ps1, ps2);//也可使用标准库的swap
置空
- release和reset均可以置空
- nullptr也可以置空
class A { public:A(){std::cout << "init" << std::endl;}~A(){std::cout << "~A" << std::endl;} };std::unique_ptr<A> ptra = std::make_unique<A>(); ptra = nullptr;// out // init // ~A
unique_ptr转shared_ptr
使用std即可