1. auto_ptr: c++11中推荐不使用他(放弃)
2. shared_ptr: 拥有共享对象所有权语义的智能指针
3. unique_ptr: 拥有独有对象所有权语义的智能指针
4. weaked_ptr: 到 std::shared_ptr 所管理对象的弱引用
1.1 unique_ptr
参考:https://zh.cppreference.com/w/cpp/memory/unique_ptr
-
std::unique_ptr
是通过指针占有并管理另一对象,并在unique_ptr
离开作用域时释放该对象的智能指针 -
在下列两者之一发生时用关联的删除器释放对象:
-
通过调用 get_deleter()(ptr) ,用潜在为用户提供的删除器释放对象。默认删除器用 delete 运算符,它销毁对象并解分配内存。
-
unique_ptr
亦可以不占有对象,该情况下称它为空 (empty)。
-
std::unique_ptr
有两个版本:-
管理个对象(例如以 new 分配)
-
管理动态分配的对象数组(例如以 new[] 分配)
-
-
类满足可移动构造 (MoveConstructible) 和可移动赋值 (MoveAssignable) 的要求,但不满足可复制构造 (CopyConstructible) 或可复制赋值 (CopyAssignable) 的要求。
1.2 注意
-
只有非 const 的
unique_ptr
能转移被管理对象的所有权给另一unique_ptr
。若对象的生存期为 const std::unique_ptr所管理,则它被限定在创建指针的作用域中。 -
std::unique_ptr
常用于管理对象的生存期,包含:-
通过正常退出和经由异常退出两者上的 受保证删除,提供异常安全,给处理拥有动态生存期的对象的类和函数
-
传递独占的拥有动态生存期的对象的所有权到函数
-
从函数获得独占的拥有动态生存期对象的所有权
-
1.3 使用方式
- unique_ptr: 在某一个特定时刻,只有一个unique_ptr管理资源
- 拷贝构造函数和 "=" 对于unique_ptr不存在
-
// UniqueObjectPtr(const UniqueObjectPtr&) = delete
// UniqueObjectPtr(UniqueObjectPtr&&) = default
// 把 资源转移给别人
#include <iostream> #include <cassert> #include <memory> using namespace std; class Object { public: Object(int id) : m_id(id) { std::cout << "init obj " << m_id << std::endl; } ~Object() { std::cout << "bye bye " << m_id << std::endl; } int id() const { return m_id; } private: int m_id; }; typedef unique_ptr<Object> UniqueObjectPtr; typedef std::shared_ptr<Object> ObjectPtr; void print(const UniqueObjectPtr& obj) { } void Transfer(UniqueObjectPtr obj) { cout << obj->id() << endl; } // unique_ptr: 在某一个特定时刻,只有一个unique_ptr管理资源 // 拷贝构造函数和 "=" 对于unique_ptr不存在 void uniquePtr() { UniqueObjectPtr obj(new Object(1)); auto p = obj.get(); if (p) { } //better if (obj) { } //operator -> * cout << p->id() << " " << obj->id() << " " << (*obj).id() << endl; print(obj); p = obj.release(); // 自身不再管理该指针 delete p; // 之后,该指针可以按常规指针处理 obj.reset(); // 把以前管理的资源调用析构 obj.reset(new Object(2)); // 1. obj.reset(); 2. 管理新的指针 // UniqueObjectPtr(const UniqueObjectPtr&) = delete // UniqueObjectPtr(UniqueObjectPtr&&) = default // 把 资源转移给别人 Transfer(std::move(obj)); // 一个unique_ptr的值, 接收右值的引用 // 违反unique_ptr规则,上一行用函数形参传入unique_ptr,对于原有obj 已经不在管理他的资源,obj掌握一个空指针 assert(obj == nullptr); // cout << obj->id() << endl; // 某种情况下, 可能有其他类型也需要使用该 资源 // 转移成其他 智能指针 obj.reset(new Object(4)) ; // 只能右值传入 ObjectPtr sharedObj(std::move(obj)); assert(obj == nullptr); // obj不再管理资源 } int main() { uniquePtr(); return 0; }