C++11引入了三个智能指针,它们分别是如下的三个:
std::shared_ptr<T>
std::unique_ptr<T>
std::weak_ptr<T>
同时C++98的智能指针auto_ptr
已经被废弃使用。
std::shared_ptr
std::shared_ptr
是共享资源所有权的指针,它对资源作引用计数,当引用计数为0时,自动的释放内存。shared_ptr
内部的引用计数是线程安全的,但是对象的读取需要加锁。
以下需要注意
- 智能指针是个模板类,可以指定类型,传入指针通过构造函数初始化。我们也可以使用make_shared函数初始化,但是不能将指针直接赋值给一个智能指针,一个是类,一个是指针。
1
2
3
4
5
int main() {
std::shared_ptr<int> sptr = new int(10); // bad
return 0;
} - 拷贝和赋值。拷贝使得对象的引用计数增加1,赋值使得原对象引用计数减1,当计数为0时,自动释放内存。后来指向的对象引用计数加1,指向后来的对象。
get
函数获取原始指针。- 注意不要用一个原始指针初始化多个
shared_ptr
指针,否则会造成内存的二次释放。 - 避免循环引用,从而造成内存的二次释放。
示例
1 |
|
一些shared_ptr
独有的操作
1 | p.use_count() // 返回与p共享对象的智能指针数量,主要用于调试,可能很慢 |
因为make_shared
是精心为异常安全实现的,建议使用make_shared
而不是直接调用的shared_ptr
构造函数。
如果不使用make_shared
,则必须先使用显式new
表达式来创建对象,然后才能将其传递到shared_ptr
构造函数。
1 | shared_ptr<int> sp2(new int(20)); |
std::unique_str
std::unique_str
是独占资源所有权的指针,同一个时刻只能有一个unique_std
指向给定对象。它不能复制到另一个,按值传递给函数,也不能在需要创建副本的任何C++标准库库中使用。我们只能够移动std::unique_str
指针,不能简单的复制和拷贝。
1 |
|
示例
如何创建unique_ptr
实例并在函数间传递这些实例。
1 | unique_ptr<Song> songFactory(const std::wstring& artist, const std::wstring& title) { |
因为make_unique
是精心为异常安全实现的,建议使用make_unique
而不是直接调用的unique_ptr
构造函数。
std::weak_ptr
std::weak_ptr
是共享资源的观察者,需要和std:shared_ptr
一起使用,不影响资源的生命周期。std::weak_ptr
可以从一个std::shared_ptr或
者另一个std::weak_ptr
对象构造,获得资源的观测权。但std::weak_ptr
没有共享资源,它的构造不会引起指针引用计数的增加。
使用std::weak_ptr
的成员函数use_count()
可以观测资源的引用计数,另一个成员函数expired()
的功能等价于use_count()==0
,但更快,表示被观测的资源(也就是std::shared_ptr
的管理的资源)已经不复存在。
weak_ptr
可以使用一个非常重要的成员函数lock()
从被观测的std::shared_ptr
获得一个可用的std::shared_ptr
对象, 从而操作资源。但当expired()==true
的时候,lock()
函数将返回一个存储空指针的std::shared_ptr
。
1 |
|