不带引用计数的智能指针
智能指针的出发点是管理堆对象,是那些不会自动释放资源的。
1、auto_ptr(C++11抛弃)
-
底层只有裸指针,独占式的,永远只让最后一个指针管理资源,只有普通的拷贝构造和赋值重载
-
基本使用:
cpp#include<iostream> #include<memory> using namespace std; int main(){ auto_ptr<int> ptr1(new int); auto_ptr<int> ptr2(ptr1); //先把ptr1底层的值记下来,再将ptr1=null,后 // 面将记下来的值return给ptr2 *ptr2 = 20; cout << *ptr1 << endl; // 程序崩溃,ptr1已经是空指针了 return 0; }
-
上面的底层逻辑:
cpp//构造函数 auto_ptr(auto_ptr& _Right) noexcept : _Myptr(_Right.release()) {} //release的实现 _Ty* release() noexcept { _Ty* _Tmp = _Myptr; _Myptr = nullptr; return _Tmp; }
-
初始化:
cpp#include <memory> int main() { //初始化方式1 std::auto_ptr<int> sp1(new int(8)); //初始化方式2 std::auto_ptr<int> sp2; sp2.reset(new int(8)); return 0; } /* void reset(_Ty* _Ptr = nullptr) noexcept { if (_Ptr != _Myptr) { delete _Myptr; } _Myptr = _Ptr; } */
-
TIP:
- 不推荐使用,可以简单的使用,不适合复杂场景
- 可以在容器里面使用
auto_ptr
吗? 不建议使用,容器底部的资源会被转移,采用的拷贝构造,明眼看不出来
2、unique_ptr
-
删除普通的拷贝构造和赋值重载,提供移动构造和移动赋值重载 ,相比于
auto_ptr
将资源的转移摆在了明面上cppunique_ptr(const unique_ptr&) = delete; unique_ptr& operator=(const unique_ptr&) = delete; // 提供了右值版本 unique_ptr(unique_ptr&& _Right); unique_ptr& operator=(unique_ptr&& _Right);
-
初始化:
cpp//初始化方式1 std::unique_ptr<int> sp1(new int(123)); //初始化方式2 std::unique_ptr<int> sp2; sp2.reset(new int(123)); //初始化方式3,这个方法更安全,但是C++14才出来 std::unique_ptr<int> sp3 = std::make_unique<int>(123);
-
基本使用:
cpp#include<iostream> #include<memory> using namespace std; int main() { unique_ptr<int> p1(new int); // unique_ptr<int> p2(p1); //直接传入左值会报错 //不能调用,会报错 attempting to reference a deleted function unique_ptr<int> p2(std::move(p1)); //先将p1转换为右值,再拷贝给p2 }
-
TIP:
- 由于右值拷贝和右值赋值重载的存在,
uniuqe_ptr
可以用于函数调用过程中
- 由于右值拷贝和右值赋值重载的存在,