C++11智能指针
C++11 引入了智能指针(Smart Pointers),旨在解决传统指针在资源管理上的常见问题,如内存泄漏、野指针等。智能指针通过自动管理资源的生命周期来减少这类问题。C++11 提供了三种主要的智能指针:std::unique_ptr
、std::shared_ptr
和 std::weak_ptr
。
C++98的auto_ptr智能指针
auto_ptr是c++98定义的智能指针模板,其定义了管理指针的对象,
可以将new获得(直接或间接)的地址赋给这种对象,当对象过期时
其析构函数将使用delete来释放内存
用法:
头文件 #include <memory>
使用: auto_ptr<类型> 变量名(new 类型)
使用忠告:
1、尽可能不要将auto_ptr变量定义为全局变量或指针
2、除非自己知道后果,不要把auto_ptr智能指针赋值给同类型的另一个智能指针
3、c++11后auto_ptr已经被“抛弃”,已使用unique_ptr代替
auto_ptr主要的弊端
1、赋值和复制会改变资源的所有权,不符合人的直觉感受
2、在STL容器中使用auto_ptr存在重大风险,因为容器内的元素必须支持可复制和可赋值
3、不支持对象数组的操作
unique_ptr智能指针
针对auto_ptr智能指针的弊端,在C++11中推出新的智能指针unique_ptr。
unique_ptr特性
1、基于排他所有权模式:两个unique_ptr不能指向同一个对象
2、无法进行左值unique_ptr复制构造,也无法进行左值复制赋值操作,
但允许临时右值复制构造和赋值(它不能复制,但可以移动)
3、保存指向某个对象的指针,当它被销毁时,它所指向的对象也会被自动删除。
4、在容器中保存的指针是安全的
unique_ptr智能指针它不能复制,但可以移动
在容器中保存的指针是安全的
支持对象数组的操作
unique_ptr的构造方式
1、unique_ptr<T> up; //空的unique_ptr,可以指向类型为T的对象
2、unique_ptr<T> up(new T()); //定义unique_ptr,同时指向类型为T的对象
3、unique_ptr<T[]> up; //空的unique_ptr,可以指向类型为T的数组对象
4、unique_ptr<T[]> up(new T[]{...}); //定义unique_ptr,同时指向类型为T的数组对象
5、unique_ptr<T,D> up; //空的unique_ptr,可以指向类型为T的对象,接收一个类型为D的删除器d,使用d释放内存
6、unique_ptr<T,D> up(new T()); //定义unique_ptr,同时指向类型为T的对象,接收一个类型为D的删除器d,使用d释放内存。
可以主动释放内存
shared_ptr智能指针
1、std::shared_ptr允许多个shared_ptr实例共享同一个对象。
当最后一个指向某个对象的shared_ptr被销毁或重置时,对象才会被删除。
2、它通过控制块来管理多个shared_ptr实例,控制块中包含一个计数器,用于跟踪当前有多少个shared_ptr指向该对象。
3、shared_ptr可以被复制和移动。
4、使用场景:当多个所有者需要共享同一个对象时,使用shared_ptr。
shared_ptr的构造
1、shared_ptr<T> s1; //空的shared_ptr,可以指向类型为T的对象
2、shared_ptr<T> s1(new T()); //定义shared_ptr,同时指向类型为T的对象
3、shared_ptr<T[]> s1; //空的shared_ptr,可以指向类型为T的数组对象(c++17后支持)
4、shared_ptr<T[]> s1(new T[]{...}); //定义shared_ptr,同时指向类型为T的数组对象(c++17后支持)
5、shared_ptr<T> s1(NULL,D()); //空的shared_ptr,可以指向类型为T的对象,接受一个为D类型的删除器d,使用d释放内存
6、shared_ptr<T> s1(new T(),D()); //定义shared_ptr,同时指向类型为T的对象,接受一个为D类型的删除器d,使用d释放内存
可以主动释放对象
重置
交换
shared_ptr智能指针的问题
shared_ptr
相互引用时的循环引用问题 。可以使用weak_ptr智能指针解决。
weak_ptr智能指针
1、std::weak_ptr是一种不拥有其所指对象的智能指针。它主要用于解决shared_ptr相互引用时的循环引用问题。
2、它不增加对象的共享计数,因此不会影响对象的销毁。
3、weak_ptr不支持*和->对指针的访问
4、weak_ptr不能单独用来访问对象,必须与shared_ptr配合使用,通过lock()方法获取shared_ptr来临时访问对象。
5、使用场景:解决shared_ptr间的循环引用问题。